geany-2.0/0000755000175000017500000000000014514253254007464 500000000000000geany-2.0/configure.ac0000644000175000017500000001200614514252267011674 00000000000000dnl Process this file with autoconf to produce a configure script. AC_PREREQ([2.60]) AC_INIT([Geany], [2.0], [https://github.com/geany/geany/issues]) AC_CONFIG_SRCDIR([src/geany.h]) AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_MACRO_DIR([m4]) AM_INIT_AUTOMAKE([1.11 -Wall parallel-tests subdir-objects]) AC_CONFIG_HEADERS([config.h]) # Silence "AC_LINK_IFELSE before AC_USE_SYSTEM_EXTENSIONS" warnings # Note: Enables _GNU_SOURCE on Linux AC_USE_SYSTEM_EXTENSIONS AM_GNU_GETTEXT_VERSION([0.19.8]) AM_GNU_GETTEXT([external]) m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])]) GEANY_PREFIX GEANY_DOCDIR GEANY_STATUS_ADD([Install Geany in], [${prefix}]) if test -n "${build}" -a -n "${target}"; then GEANY_STATUS_ADD([Building Geany on], [${build}]) GEANY_STATUS_ADD([Building Geany for], [${target}]) fi m4_ifdef([AM_PROG_AR],[AM_PROG_AR]) LT_INIT([disable-static]) AC_PROG_CC AM_PROG_CC_C_O AC_PROG_CXX GEANY_PROG_CXX AX_CXX_COMPILE_STDCXX_17 AC_PROG_INSTALL AC_PROG_LN_S if test "$ac_cv_prog_cc_c99" = "no"; then AC_MSG_ERROR([Need a C99 compiler]) fi # autoscan start # Checks for header files. AC_CHECK_HEADERS([fcntl.h stdlib.h sys/time.h errno.h limits.h]) # Checks for dependencies needed by ctags AC_CHECK_HEADERS([dirent.h fnmatch.h direct.h io.h sys/dir.h]) AC_DEFINE([HAVE_STDBOOL_H], [1], [whether or not to use .]) AC_CHECK_FUNC([regcomp], [have_regcomp=yes], [have_regcomp=no dnl various stuff for ctags/gnu_regex/ AC_CHECK_HEADERS([langinfo.h locale.h libintl.h wctype.h wchar.h]) AC_CHECK_FUNCS([memcpy isblank wcrtomb mbrtowc wcscoll]) AC_FUNC_ALLOCA]) AM_CONDITIONAL([USE_BUNDLED_REGEX], [test "xno" = "x$have_regcomp"]) AC_CHECK_FUNC([fnmatch], [have_fnmatch=yes], [have_fnmatch=no]) AM_CONDITIONAL([USE_BUNDLED_FNMATCH], [test "xno" = "x$have_fnmatch"]) # Checks for typedefs, structures, and compiler characteristics. AC_TYPE_OFF_T AC_TYPE_SIZE_T AC_STRUCT_TM # Checks for library functions. AC_CHECK_FUNCS([realpath]) # Function checks for u-ctags AC_CHECK_FUNCS([strerror strstr asprintf]) AC_CHECK_FUNCS([mkstemp tempnam], [break]) AC_CHECK_FUNCS([strcasecmp stricmp], [break]) AC_CHECK_FUNCS([strncasecmp strnicmp], [break]) AC_CHECK_FUNCS([truncate ftruncate chsize], [break]) # non-functions checks for u-ctags. Not that we really need those as we don't # use u-ctags's main, but the corresponding macros have to be defined to # something, so simply perform the actual checks. AC_CHECK_DECLS([__environ],,,[[#include ]]) AC_CHECK_DECLS([_NSGetEnviron],,,[[#include ]]) # autoscan end # check for VCS revision GEANY_CHECK_REVISION([dnl force debug mode for a VCS working copy CFLAGS="-g -DGEANY_DEBUG $CFLAGS"]) GEANY_CHECK_GTK GEANY_CHECK_GTK_FUNCS([g_strv_equal]) # --disable-deprecated switch for GTK purification AC_ARG_ENABLE([deprecated], [AS_HELP_STRING([--disable-deprecated], [Disable deprecated GTK functions.])], [GTK_CFLAGS="$GTK_CFLAGS -DG_DISABLE_DEPRECATED -DGTK_DISABLE_DEPRECATED"], []) # Check for binary relocation support GEANY_CHECK_BINRELOC # CTags source compatibility (we actually use GRegex instead of POSIX regcomp) AC_DEFINE([HAVE_REGCOMP], [1], [Should always be 1, required for CTags.]) # Plugins support GEANY_CHECK_PLUGINS # check for mingw specific settings GEANY_CHECK_MINGW GEANY_CHECK_SOCKET GEANY_CHECK_VTE GEANY_CHECK_MAC_INTEGRATION GEANY_CHECK_THE_FORCE dnl hehe AC_SUBST([GETTEXT_PACKAGE],[$PACKAGE]) AC_DEFINE_UNQUOTED([GETTEXT_PACKAGE], ["$PACKAGE"], [Gettext package.]) # double eval since datarootdir is usually defined as ${prefix}/share AM_COND_IF([MINGW], [pkgdatadir='${prefix}/data'], [pkgdatadir='${datarootdir}/geany']) AM_COND_IF([MINGW],[LIBS="$LIBS -liconv"]) AC_SUBST([GEANY_DATA_DIR], [$(eval echo $(eval echo $pkgdatadir))]) AC_SUBST([pkgdatadir]) # The default Python command. On Windows, use the `py` launcher by default AC_ARG_WITH([python-command], [AS_HELP_STRING([--with-python-command], [the default Python command [defaults to "py" on Windows and "python" otherwise]])], [with_python_command=$withval], [with_python_command=auto]) AS_IF([test "x$with_python_command" = xauto], [AM_COND_IF([MINGW], [with_python_command=py], [with_python_command=python])]) AC_SUBST([PYTHON_COMMAND], [$with_python_command]) # Documentation tools GEANY_CHECK_DOCUTILS GEANY_CHECK_DOXYGEN GEANY_CHECK_GTKDOC_HEADER # libgeany GEANY_LIB_INIT # Output AC_CONFIG_FILES([ Makefile icons/Makefile icons/16x16/Makefile icons/24x24/Makefile icons/32x32/Makefile icons/48x48/Makefile icons/scalable/Makefile icons/tango/Makefile icons/tango/16x16/Makefile icons/tango/24x24/Makefile icons/tango/32x32/Makefile icons/tango/48x48/Makefile icons/tango/scalable/Makefile ctags/Makefile scintilla/Makefile src/Makefile src/tagmanager/Makefile plugins/Makefile po/Makefile.in data/Makefile data/filedefs/filetypes.python doc/Makefile doc/geany.1 geany.pc geany.nsi tests/Makefile tests/ctags/Makefile ]) AC_OUTPUT # Summary GEANY_STATUS_OUTPUT echo "" echo "Configuration is done OK." echo "" geany-2.0/configure0000754000175000017500000316026214514252331011317 00000000000000#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.71 for Geany 2.0. # # Report bugs to . # # # Copyright (C) 1992-1996, 1998-2017, 2020-2021 Free Software Foundation, # Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh as_nop=: if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else $as_nop case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi # Reset variables that may have inherited troublesome values from # the environment. # IFS needs to be set, to space, tab, and newline, in precisely that order. # (If _AS_PATH_WALK were called with IFS unset, it would have the # side effect of setting IFS to empty, thus disabling word splitting.) # Quoting is to prevent editors from complaining about space-tab. as_nl=' ' export as_nl IFS=" "" $as_nl" PS1='$ ' PS2='> ' PS4='+ ' # Ensure predictable behavior from utilities with locale-dependent output. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # We cannot yet rely on "unset" to work, but we need these variables # to be unset--not just set to an empty or harmless value--now, to # avoid bugs in old shells (e.g. pre-3.0 UWIN ksh). This construct # also avoids known problems related to "unset" and subshell syntax # in other old shells (e.g. bash 2.01 and pdksh 5.2.14). for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH do eval test \${$as_var+y} \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done # Ensure that fds 0, 1, and 2 are open. if (exec 3>&0) 2>/dev/null; then :; else exec 0&1) 2>/dev/null; then :; else exec 1>/dev/null; fi if (exec 3>&2) ; then :; else exec 2>/dev/null; fi # The user is always right. if ${PATH_SEPARATOR+false} :; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac test -r "$as_dir$0" && as_myself=$as_dir$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Use a proper internal environment variable to ensure we don't fall # into an infinite loop, continuously re-executing ourselves. if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then _as_can_reexec=no; export _as_can_reexec; # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi # We don't want this to propagate to other subprocesses. { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="as_nop=: if test \${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else \$as_nop case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ) then : else \$as_nop exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1 blah=\$(echo \$(echo blah)) test x\"\$blah\" = xblah || exit 1 test -x / || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 test \$(( 1 + 1 )) = 2 || exit 1 test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO PATH=/empty FPATH=/empty; export PATH FPATH test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1" if (eval "$as_required") 2>/dev/null then : as_have_required=yes else $as_nop as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null then : else $as_nop as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && as_run=a "$as_shell" -c "$as_bourne_compatible""$as_required" 2>/dev/null then : CONFIG_SHELL=$as_shell as_have_required=yes if as_run=a "$as_shell" -c "$as_bourne_compatible""$as_suggested" 2>/dev/null then : break 2 fi fi done;; esac as_found=false done IFS=$as_save_IFS if $as_found then : else $as_nop if { test -f "$SHELL" || test -f "$SHELL.exe"; } && as_run=a "$SHELL" -c "$as_bourne_compatible""$as_required" 2>/dev/null then : CONFIG_SHELL=$SHELL as_have_required=yes fi fi if test "x$CONFIG_SHELL" != x then : export CONFIG_SHELL # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi if test x$as_have_required = xno then : printf "%s\n" "$0: This script requires a shell more modern than all" printf "%s\n" "$0: the shells that I found on your system." if test ${ZSH_VERSION+y} ; then printf "%s\n" "$0: In particular, zsh $ZSH_VERSION has bugs and should" printf "%s\n" "$0: be upgraded to zsh 4.3.4 or later." else printf "%s\n" "$0: Please tell bug-autoconf@gnu.org and $0: https://github.com/geany/geany/issues about your $0: system, including any error possibly output before this $0: message. Then install a modern shell, or manually run $0: the script under such a shell if you do have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_nop # --------- # Do nothing but, unlike ":", preserve the value of $?. as_fn_nop () { return $? } as_nop=as_fn_nop # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null then : eval 'as_fn_append () { eval $1+=\$2 }' else $as_nop as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null then : eval 'as_fn_arith () { as_val=$(( $* )) }' else $as_nop as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_nop # --------- # Do nothing but, unlike ":", preserve the value of $?. as_fn_nop () { return $? } as_nop=as_fn_nop # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi printf "%s\n" "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { printf "%s\n" "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # If we had to re-execute with $CONFIG_SHELL, we're ensured to have # already done that, so ensure we don't try to do so again and fall # in an infinite loop. This has already happened in practice. _as_can_reexec=no; export _as_can_reexec # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } # Determine whether it's possible to make 'echo' print without a newline. # These variables are no longer used directly by Autoconf, but are AC_SUBSTed # for compatibility with existing Makefiles. ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac # For backward compatibility with old third-party macros, we provide # the shell variables $as_echo and $as_echo_n. New code should use # AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively. as_echo='printf %s\n' as_echo_n='printf %s' rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" SHELL=${CONFIG_SHELL-/bin/sh} test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME='Geany' PACKAGE_TARNAME='geany' PACKAGE_VERSION='2.0' PACKAGE_STRING='Geany 2.0' PACKAGE_BUGREPORT='https://github.com/geany/geany/issues' PACKAGE_URL='' ac_unique_file="src/geany.h" # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_STDIO_H # include #endif #ifdef HAVE_STDLIB_H # include #endif #ifdef HAVE_STRING_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_header_c_list= gt_needs= ac_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS LIBOBJS UNIQ SORT LIBGEANY_LDFLAGS LIBGEANY_CFLAGS LIBGEANY_EXPORT_CFLAGS ENABLE_GTKDOC_HEADER_FALSE ENABLE_GTKDOC_HEADER_TRUE pkgpyexecdir pyexecdir pkgpythondir pythondir PYTHON_EXEC_PREFIX PYTHON_PREFIX PYTHON_PLATFORM PYTHON_VERSION PYTHON WITH_DOXYGEN_FALSE WITH_DOXYGEN_TRUE DOXYGEN WITH_RST2PDF_FALSE WITH_RST2PDF_TRUE RST2PDF INSTALL_HTML_DOCS_FALSE INSTALL_HTML_DOCS_TRUE WITH_RST2HTML_FALSE WITH_RST2HTML_TRUE RST2HTML PYTHON_COMMAND pkgdatadir GEANY_DATA_DIR GETTEXT_PACKAGE MAC_INTEGRATION_LIBS MAC_INTEGRATION_CFLAGS ENABLE_MAC_INTEGRATION_FALSE ENABLE_MAC_INTEGRATION_TRUE MINGW_FALSE MINGW_TRUE PLUGINS_FALSE PLUGINS_TRUE ENABLE_BINRELOC_FALSE ENABLE_BINRELOC_TRUE GTK_VERSION DEPENDENCIES GTK_LIBS GTK_CFLAGS PKG_CONFIG_LIBDIR PKG_CONFIG_PATH PKG_CONFIG USE_BUNDLED_FNMATCH_FALSE USE_BUNDLED_FNMATCH_TRUE USE_BUNDLED_REGEX_FALSE USE_BUNDLED_REGEX_TRUE ALLOCA HAVE_CXX17 CXXCPP am__fastdepCXX_FALSE am__fastdepCXX_TRUE CXXDEPMODE ac_ct_CXX CXXFLAGS CXX LT_SYS_LIBRARY_PATH OTOOL64 OTOOL LIPO NMEDIT DSYMUTIL MANIFEST_TOOL RANLIB DLLTOOL OBJDUMP FILECMD LN_S NM ac_ct_DUMPBIN DUMPBIN LD FGREP LIBTOOL ac_ct_AR AR POSUB LTLIBINTL LIBINTL INTLLIBS LTLIBICONV LIBICONV INTL_MACOSX_LIBS EGREP GREP CPP host_os host_vendor host_cpu host build_os build_vendor build_cpu build XGETTEXT_EXTRA_OPTIONS MSGMERGE XGETTEXT_015 XGETTEXT GMSGFMT_015 MSGFMT_015 GMSGFMT MSGFMT GETTEXT_MACRO_VERSION USE_NLS SED am__fastdepCC_FALSE am__fastdepCC_TRUE CCDEPMODE am__nodep AMDEPBACKSLASH AMDEP_FALSE AMDEP_TRUE am__include DEPDIR OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CFLAGS CC AM_BACKSLASH AM_DEFAULT_VERBOSITY AM_DEFAULT_V AM_V CSCOPE ETAGS CTAGS am__untar am__tar AMTAR am__leading_dot SET_MAKE AWK mkdir_p MKDIR_P INSTALL_STRIP_PROGRAM STRIP install_sh MAKEINFO AUTOHEADER AUTOMAKE AUTOCONF ACLOCAL VERSION PACKAGE CYGPATH_W am__isrc INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir runstatedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL am__quote' ac_subst_files='' ac_user_opts=' enable_option_checking enable_silent_rules enable_dependency_tracking enable_nls with_gnu_ld enable_rpath with_libiconv_prefix with_libintl_prefix enable_static enable_shared with_pic enable_fast_install with_aix_soname with_sysroot enable_libtool_lock enable_deprecated enable_binreloc enable_plugins enable_vte with_vte_module_path enable_socket enable_mac_integration enable_the_force with_python_command enable_html_docs enable_pdf_docs enable_api_docs enable_gtkdoc_header with_python_sys_prefix with_python_prefix with_python_exec_prefix ' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS CPP LT_SYS_LIBRARY_PATH CXX CXXFLAGS CCC CXXCPP PKG_CONFIG PKG_CONFIG_PATH PKG_CONFIG_LIBDIR GTK_CFLAGS GTK_LIBS MAC_INTEGRATION_CFLAGS MAC_INTEGRATION_LIBS RST2HTML RST2PDF DOXYGEN PYTHON' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *=) ac_optarg= ;; *) ac_optarg=yes ;; esac case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: \`$ac_useropt'" ac_useropt_orig=$ac_useropt ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: \`$ac_useropt'" ac_useropt_orig=$ac_useropt ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -runstatedir | --runstatedir | --runstatedi | --runstated \ | --runstate | --runstat | --runsta | --runst | --runs \ | --run | --ru | --r) ac_prev=runstatedir ;; -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ | --run=* | --ru=* | --r=*) runstatedir=$ac_optarg ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: \`$ac_useropt'" ac_useropt_orig=$ac_useropt ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: \`$ac_useropt'" ac_useropt_orig=$ac_useropt ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error $? "unrecognized option: \`$ac_option' Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. printf "%s\n" "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && printf "%s\n" "$as_me: WARNING: invalid host type: $ac_option" >&2 : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir runstatedir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures Geany 2.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/geany] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF Program names: --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names System types: --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of Geany 2.0:";; esac cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-silent-rules less verbose build output (undo: "make V=1") --disable-silent-rules verbose build output (undo: "make V=0") --enable-dependency-tracking do not reject slow dependency extractors --disable-dependency-tracking speeds up one-time build --disable-nls do not use Native Language Support --disable-rpath do not hardcode runtime library paths --enable-static[=PKGS] build static libraries [default=no] --enable-shared[=PKGS] build shared libraries [default=yes] --enable-fast-install[=PKGS] optimize for fast installation [default=yes] --disable-libtool-lock avoid locking (might break parallel builds) --disable-deprecated Disable deprecated GTK functions. --enable-binreloc compile with binary relocation support [default=no] --disable-plugins compile without plugin support [default=no] --enable-vte enable if you want virtual terminal support [default=yes] --enable-socket enable if you want to detect a running instance [default=yes] --enable-mac-integration use gtk-mac-integration to enable improved OS X integration [default=no] --enable-the-force enable if you are Luke Skywalker and the force is with you [default=no] --enable-html-docs generate HTML documentation using rst2html [default=auto] --enable-pdf-docs generate PDF documentation using rst2pdf [default=auto] --enable-api-docs generate API documentation using Doxygen [default=auto] --enable-gtkdoc-header generate the GtkDoc header suitable for GObject introspection [default=auto] Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-gnu-ld assume the C compiler uses GNU ld [default=no] --with-libiconv-prefix[=DIR] search for libiconv in DIR/include and DIR/lib --without-libiconv-prefix don't search for libiconv in includedir and libdir --with-libintl-prefix[=DIR] search for libintl in DIR/include and DIR/lib --without-libintl-prefix don't search for libintl in includedir and libdir --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use both] --with-aix-soname=aix|svr4|both shared library versioning (aka "SONAME") variant to provide on AIX, [default=aix]. --with-gnu-ld assume the C compiler uses GNU ld [default=no] --with-sysroot[=DIR] Search for dependent libraries within DIR (or the compiler's sysroot if not specified). --with-vte-module-path=PATH Path to a loadable libvte [default=None] --with-python-command the default Python command [defaults to "py" on Windows and "python" otherwise] --with-python-sys-prefix use Python's sys.prefix and sys.exec_prefix values --with-python_prefix override the default PYTHON_PREFIX --with-python_exec_prefix override the default PYTHON_EXEC_PREFIX Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CPP C preprocessor LT_SYS_LIBRARY_PATH User-defined run-time library search path. CXX C++ compiler command CXXFLAGS C++ compiler flags CXXCPP C++ preprocessor PKG_CONFIG path to pkg-config utility PKG_CONFIG_PATH directories to add to pkg-config's search path PKG_CONFIG_LIBDIR path overriding pkg-config's built-in search path GTK_CFLAGS C compiler flags for GTK, overriding pkg-config GTK_LIBS linker flags for GTK, overriding pkg-config MAC_INTEGRATION_CFLAGS C compiler flags for MAC_INTEGRATION, overriding pkg-config MAC_INTEGRATION_LIBS linker flags for MAC_INTEGRATION, overriding pkg-config RST2HTML Path to Docutils rst2html executable RST2PDF Path to Docutils rst2pdf executable DOXYGEN Path to Doxygen executable PYTHON the Python interpreter Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to . _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for configure.gnu first; this name is used for a wrapper for # Metaconfig's "Configure" on case-insensitive file systems. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else printf "%s\n" "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF Geany configure 2.0 generated by GNU Autoconf 2.71 Copyright (C) 2021 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_c_try_compile LINENO # -------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest.beam if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext then : ac_retval=0 else $as_nop printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_compile # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in # INCLUDES, setting the cache variable VAR accordingly. ac_fn_c_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 printf %s "checking for $2... " >&6; } if eval test \${$3+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO" then : eval "$3=yes" else $as_nop eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi eval ac_res=\$$3 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 printf "%s\n" "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_compile # ac_fn_c_try_cpp LINENO # ---------------------- # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err } then : ac_retval=0 else $as_nop printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_cpp # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest.beam conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || test -x conftest$ac_exeext } then : ac_retval=0 else $as_nop printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_link # ac_fn_c_try_run LINENO # ---------------------- # Try to run conftest.$ac_ext, and return whether this succeeded. Assumes that # executables *can* be run. ac_fn_c_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; } then : ac_retval=0 else $as_nop printf "%s\n" "$as_me: program exited with status $ac_status" >&5 printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_run # ac_fn_c_check_func LINENO FUNC VAR # ---------------------------------- # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_c_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 printf %s "checking for $2... " >&6; } if eval test \${$3+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. For example, HP-UX 11i declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $2 (); below. */ #include #undef $2 /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $2 (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$2 || defined __stub___$2 choke me #endif int main (void) { return $2 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : eval "$3=yes" else $as_nop eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 printf "%s\n" "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_func # ac_fn_cxx_try_compile LINENO # ---------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest.beam if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext then : ac_retval=0 else $as_nop printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_compile # ac_fn_cxx_try_cpp LINENO # ------------------------ # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err } then : ac_retval=0 else $as_nop printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_cpp # ac_fn_cxx_try_link LINENO # ------------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest.beam conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || test -x conftest$ac_exeext } then : ac_retval=0 else $as_nop printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_link # ac_fn_c_check_type LINENO TYPE VAR INCLUDES # ------------------------------------------- # Tests whether TYPE exists after having included INCLUDES, setting cache # variable VAR accordingly. ac_fn_c_check_type () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 printf %s "checking for $2... " >&6; } if eval test \${$3+y} then : printf %s "(cached) " >&6 else $as_nop eval "$3=no" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main (void) { if (sizeof ($2)) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main (void) { if (sizeof (($2))) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : else $as_nop eval "$3=yes" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi eval ac_res=\$$3 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 printf "%s\n" "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_type # ac_fn_check_decl LINENO SYMBOL VAR INCLUDES EXTRA-OPTIONS FLAG-VAR # ------------------------------------------------------------------ # Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR # accordingly. Pass EXTRA-OPTIONS to the compiler, using FLAG-VAR. ac_fn_check_decl () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack as_decl_name=`echo $2|sed 's/ *(.*//'` { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5 printf %s "checking whether $as_decl_name is declared... " >&6; } if eval test \${$3+y} then : printf %s "(cached) " >&6 else $as_nop as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'` eval ac_save_FLAGS=\$$6 as_fn_append $6 " $5" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main (void) { #ifndef $as_decl_name #ifdef __cplusplus (void) $as_decl_use; #else (void) $as_decl_name; #endif #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : eval "$3=yes" else $as_nop eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext eval $6=\$ac_save_FLAGS fi eval ac_res=\$$3 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 printf "%s\n" "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_check_decl ac_configure_args_raw= for ac_arg do case $ac_arg in *\'*) ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append ac_configure_args_raw " '$ac_arg'" done case $ac_configure_args_raw in *$as_nl*) ac_safe_unquote= ;; *) ac_unsafe_z='|&;<>()$`\\"*?[ '' ' # This string ends in space, tab. ac_unsafe_a="$ac_unsafe_z#~" ac_safe_unquote="s/ '\\([^$ac_unsafe_a][^$ac_unsafe_z]*\\)'/ \\1/g" ac_configure_args_raw=` printf "%s\n" "$ac_configure_args_raw" | sed "$ac_safe_unquote"`;; esac cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by Geany $as_me 2.0, which was generated by GNU Autoconf 2.71. Invocation command line was $ $0$ac_configure_args_raw _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac printf "%s\n" "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Sanitize IFS. IFS=" "" $as_nl" # Save into config.log some information that might help in debugging. { echo printf "%s\n" "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo printf "%s\n" "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac printf "%s\n" "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then printf "%s\n" "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac printf "%s\n" "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then printf "%s\n" "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && printf "%s\n" "$as_me: caught signal $ac_signal" printf "%s\n" "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h printf "%s\n" "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. printf "%s\n" "#define PACKAGE_NAME \"$PACKAGE_NAME\"" >>confdefs.h printf "%s\n" "#define PACKAGE_TARNAME \"$PACKAGE_TARNAME\"" >>confdefs.h printf "%s\n" "#define PACKAGE_VERSION \"$PACKAGE_VERSION\"" >>confdefs.h printf "%s\n" "#define PACKAGE_STRING \"$PACKAGE_STRING\"" >>confdefs.h printf "%s\n" "#define PACKAGE_BUGREPORT \"$PACKAGE_BUGREPORT\"" >>confdefs.h printf "%s\n" "#define PACKAGE_URL \"$PACKAGE_URL\"" >>confdefs.h # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. if test -n "$CONFIG_SITE"; then ac_site_files="$CONFIG_SITE" elif test "x$prefix" != xNONE; then ac_site_files="$prefix/share/config.site $prefix/etc/config.site" else ac_site_files="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" fi for ac_site_file in $ac_site_files do case $ac_site_file in #( */*) : ;; #( *) : ac_site_file=./$ac_site_file ;; esac if test -f "$ac_site_file" && test -r "$ac_site_file"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 printf "%s\n" "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5; } fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 printf "%s\n" "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 printf "%s\n" "$as_me: creating cache $cache_file" >&6;} >$cache_file fi as_fn_append ac_header_c_list " stdio.h stdio_h HAVE_STDIO_H" # Test code for whether the C compiler supports C89 (global declarations) ac_c_conftest_c89_globals=' /* Does the compiler advertise C89 conformance? Do not test the value of __STDC__, because some compilers set it to 0 while being otherwise adequately conformant. */ #if !defined __STDC__ # error "Compiler does not advertise C89 conformance" #endif #include #include struct stat; /* Most of the following tests are stolen from RCS 5.7 src/conf.sh. */ struct buf { int x; }; struct buf * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not \xHH hex character constants. These do not provoke an error unfortunately, instead are silently treated as an "x". The following induces an error, until -std is added to get proper ANSI mode. Curiously \x00 != x always comes out true, for an array size at least. It is necessary to write \x00 == 0 to get something that is true only with -std. */ int osf4_cc_array ['\''\x00'\'' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) '\''x'\'' int xlc6_cc_array[FOO(a) == '\''x'\'' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, int *(*)(struct buf *, struct stat *, int), int, int);' # Test code for whether the C compiler supports C89 (body of main). ac_c_conftest_c89_main=' ok |= (argc == 0 || f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]); ' # Test code for whether the C compiler supports C99 (global declarations) ac_c_conftest_c99_globals=' // Does the compiler advertise C99 conformance? #if !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L # error "Compiler does not advertise C99 conformance" #endif #include extern int puts (const char *); extern int printf (const char *, ...); extern int dprintf (int, const char *, ...); extern void *malloc (size_t); // Check varargs macros. These examples are taken from C99 6.10.3.5. // dprintf is used instead of fprintf to avoid needing to declare // FILE and stderr. #define debug(...) dprintf (2, __VA_ARGS__) #define showlist(...) puts (#__VA_ARGS__) #define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__)) static void test_varargs_macros (void) { int x = 1234; int y = 5678; debug ("Flag"); debug ("X = %d\n", x); showlist (The first, second, and third items.); report (x>y, "x is %d but y is %d", x, y); } // Check long long types. #define BIG64 18446744073709551615ull #define BIG32 4294967295ul #define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0) #if !BIG_OK #error "your preprocessor is broken" #endif #if BIG_OK #else #error "your preprocessor is broken" #endif static long long int bignum = -9223372036854775807LL; static unsigned long long int ubignum = BIG64; struct incomplete_array { int datasize; double data[]; }; struct named_init { int number; const wchar_t *name; double average; }; typedef const char *ccp; static inline int test_restrict (ccp restrict text) { // See if C++-style comments work. // Iterate through items via the restricted pointer. // Also check for declarations in for loops. for (unsigned int i = 0; *(text+i) != '\''\0'\''; ++i) continue; return 0; } // Check varargs and va_copy. static bool test_varargs (const char *format, ...) { va_list args; va_start (args, format); va_list args_copy; va_copy (args_copy, args); const char *str = ""; int number = 0; float fnumber = 0; while (*format) { switch (*format++) { case '\''s'\'': // string str = va_arg (args_copy, const char *); break; case '\''d'\'': // int number = va_arg (args_copy, int); break; case '\''f'\'': // float fnumber = va_arg (args_copy, double); break; default: break; } } va_end (args_copy); va_end (args); return *str && number && fnumber; } ' # Test code for whether the C compiler supports C99 (body of main). ac_c_conftest_c99_main=' // Check bool. _Bool success = false; success |= (argc != 0); // Check restrict. if (test_restrict ("String literal") == 0) success = true; char *restrict newvar = "Another string"; // Check varargs. success &= test_varargs ("s, d'\'' f .", "string", 65, 34.234); test_varargs_macros (); // Check flexible array members. struct incomplete_array *ia = malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10)); ia->datasize = 10; for (int i = 0; i < ia->datasize; ++i) ia->data[i] = i * 1.234; // Check named initializers. struct named_init ni = { .number = 34, .name = L"Test wide string", .average = 543.34343, }; ni.number = 58; int dynamic_array[ni.number]; dynamic_array[0] = argv[0][0]; dynamic_array[ni.number - 1] = 543; // work around unused variable warnings ok |= (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == '\''x'\'' || dynamic_array[ni.number - 1] != 543); ' # Test code for whether the C compiler supports C11 (global declarations) ac_c_conftest_c11_globals=' // Does the compiler advertise C11 conformance? #if !defined __STDC_VERSION__ || __STDC_VERSION__ < 201112L # error "Compiler does not advertise C11 conformance" #endif // Check _Alignas. char _Alignas (double) aligned_as_double; char _Alignas (0) no_special_alignment; extern char aligned_as_int; char _Alignas (0) _Alignas (int) aligned_as_int; // Check _Alignof. enum { int_alignment = _Alignof (int), int_array_alignment = _Alignof (int[100]), char_alignment = _Alignof (char) }; _Static_assert (0 < -_Alignof (int), "_Alignof is signed"); // Check _Noreturn. int _Noreturn does_not_return (void) { for (;;) continue; } // Check _Static_assert. struct test_static_assert { int x; _Static_assert (sizeof (int) <= sizeof (long int), "_Static_assert does not work in struct"); long int y; }; // Check UTF-8 literals. #define u8 syntax error! char const utf8_literal[] = u8"happens to be ASCII" "another string"; // Check duplicate typedefs. typedef long *long_ptr; typedef long int *long_ptr; typedef long_ptr long_ptr; // Anonymous structures and unions -- taken from C11 6.7.2.1 Example 1. struct anonymous { union { struct { int i; int j; }; struct { int k; long int l; } w; }; int m; } v1; ' # Test code for whether the C compiler supports C11 (body of main). ac_c_conftest_c11_main=' _Static_assert ((offsetof (struct anonymous, i) == offsetof (struct anonymous, w.k)), "Anonymous union alignment botch"); v1.i = 2; v1.w.k = 5; ok |= v1.i != 5; ' # Test code for whether the C compiler supports C11 (complete). ac_c_conftest_c11_program="${ac_c_conftest_c89_globals} ${ac_c_conftest_c99_globals} ${ac_c_conftest_c11_globals} int main (int argc, char **argv) { int ok = 0; ${ac_c_conftest_c89_main} ${ac_c_conftest_c99_main} ${ac_c_conftest_c11_main} return ok; } " # Test code for whether the C compiler supports C99 (complete). ac_c_conftest_c99_program="${ac_c_conftest_c89_globals} ${ac_c_conftest_c99_globals} int main (int argc, char **argv) { int ok = 0; ${ac_c_conftest_c89_main} ${ac_c_conftest_c99_main} return ok; } " # Test code for whether the C compiler supports C89 (complete). ac_c_conftest_c89_program="${ac_c_conftest_c89_globals} int main (int argc, char **argv) { int ok = 0; ${ac_c_conftest_c89_main} return ok; } " as_fn_append ac_header_c_list " stdlib.h stdlib_h HAVE_STDLIB_H" as_fn_append ac_header_c_list " string.h string_h HAVE_STRING_H" as_fn_append ac_header_c_list " inttypes.h inttypes_h HAVE_INTTYPES_H" as_fn_append ac_header_c_list " stdint.h stdint_h HAVE_STDINT_H" as_fn_append ac_header_c_list " strings.h strings_h HAVE_STRINGS_H" as_fn_append ac_header_c_list " sys/stat.h sys_stat_h HAVE_SYS_STAT_H" as_fn_append ac_header_c_list " sys/types.h sys_types_h HAVE_SYS_TYPES_H" as_fn_append ac_header_c_list " unistd.h unistd_h HAVE_UNISTD_H" as_fn_append ac_header_c_list " wchar.h wchar_h HAVE_WCHAR_H" as_fn_append ac_header_c_list " minix/config.h minix_config_h HAVE_MINIX_CONFIG_H" gt_needs="$gt_needs " # Test code for whether the C++ compiler supports C++98 (global declarations) ac_cxx_conftest_cxx98_globals=' // Does the compiler advertise C++98 conformance? #if !defined __cplusplus || __cplusplus < 199711L # error "Compiler does not advertise C++98 conformance" #endif // These inclusions are to reject old compilers that // lack the unsuffixed header files. #include #include // and are *not* freestanding headers in C++98. extern void assert (int); namespace std { extern int strcmp (const char *, const char *); } // Namespaces, exceptions, and templates were all added after "C++ 2.0". using std::exception; using std::strcmp; namespace { void test_exception_syntax() { try { throw "test"; } catch (const char *s) { // Extra parentheses suppress a warning when building autoconf itself, // due to lint rules shared with more typical C programs. assert (!(strcmp) (s, "test")); } } template struct test_template { T const val; explicit test_template(T t) : val(t) {} template T add(U u) { return static_cast(u) + val; } }; } // anonymous namespace ' # Test code for whether the C++ compiler supports C++98 (body of main) ac_cxx_conftest_cxx98_main=' assert (argc); assert (! argv[0]); { test_exception_syntax (); test_template tt (2.0); assert (tt.add (4) == 6.0); assert (true && !false); } ' # Test code for whether the C++ compiler supports C++11 (global declarations) ac_cxx_conftest_cxx11_globals=' // Does the compiler advertise C++ 2011 conformance? #if !defined __cplusplus || __cplusplus < 201103L # error "Compiler does not advertise C++11 conformance" #endif namespace cxx11test { constexpr int get_val() { return 20; } struct testinit { int i; double d; }; class delegate { public: delegate(int n) : n(n) {} delegate(): delegate(2354) {} virtual int getval() { return this->n; }; protected: int n; }; class overridden : public delegate { public: overridden(int n): delegate(n) {} virtual int getval() override final { return this->n * 2; } }; class nocopy { public: nocopy(int i): i(i) {} nocopy() = default; nocopy(const nocopy&) = delete; nocopy & operator=(const nocopy&) = delete; private: int i; }; // for testing lambda expressions template Ret eval(Fn f, Ret v) { return f(v); } // for testing variadic templates and trailing return types template auto sum(V first) -> V { return first; } template auto sum(V first, Args... rest) -> V { return first + sum(rest...); } } ' # Test code for whether the C++ compiler supports C++11 (body of main) ac_cxx_conftest_cxx11_main=' { // Test auto and decltype auto a1 = 6538; auto a2 = 48573953.4; auto a3 = "String literal"; int total = 0; for (auto i = a3; *i; ++i) { total += *i; } decltype(a2) a4 = 34895.034; } { // Test constexpr short sa[cxx11test::get_val()] = { 0 }; } { // Test initializer lists cxx11test::testinit il = { 4323, 435234.23544 }; } { // Test range-based for int array[] = {9, 7, 13, 15, 4, 18, 12, 10, 5, 3, 14, 19, 17, 8, 6, 20, 16, 2, 11, 1}; for (auto &x : array) { x += 23; } } { // Test lambda expressions using cxx11test::eval; assert (eval ([](int x) { return x*2; }, 21) == 42); double d = 2.0; assert (eval ([&](double x) { return d += x; }, 3.0) == 5.0); assert (d == 5.0); assert (eval ([=](double x) mutable { return d += x; }, 4.0) == 9.0); assert (d == 5.0); } { // Test use of variadic templates using cxx11test::sum; auto a = sum(1); auto b = sum(1, 2); auto c = sum(1.0, 2.0, 3.0); } { // Test constructor delegation cxx11test::delegate d1; cxx11test::delegate d2(); cxx11test::delegate d3(45); } { // Test override and final cxx11test::overridden o1(55464); } { // Test nullptr char *c = nullptr; } { // Test template brackets test_template<::test_template> v(test_template(12)); } { // Unicode literals char const *utf8 = u8"UTF-8 string \u2500"; char16_t const *utf16 = u"UTF-8 string \u2500"; char32_t const *utf32 = U"UTF-32 string \u2500"; } ' # Test code for whether the C compiler supports C++11 (complete). ac_cxx_conftest_cxx11_program="${ac_cxx_conftest_cxx98_globals} ${ac_cxx_conftest_cxx11_globals} int main (int argc, char **argv) { int ok = 0; ${ac_cxx_conftest_cxx98_main} ${ac_cxx_conftest_cxx11_main} return ok; } " # Test code for whether the C compiler supports C++98 (complete). ac_cxx_conftest_cxx98_program="${ac_cxx_conftest_cxx98_globals} int main (int argc, char **argv) { int ok = 0; ${ac_cxx_conftest_cxx98_main} return ok; } " # Auxiliary files required by this configure script. ac_aux_files="ltmain.sh ar-lib config.guess config.sub config.rpath compile missing install-sh" # Locations in which to look for auxiliary files. ac_aux_dir_candidates="${srcdir}/build-aux" # Search for a directory containing all of the required auxiliary files, # $ac_aux_files, from the $PATH-style list $ac_aux_dir_candidates. # If we don't find one directory that contains all the files we need, # we report the set of missing files from the *first* directory in # $ac_aux_dir_candidates and give up. ac_missing_aux_files="" ac_first_candidate=: printf "%s\n" "$as_me:${as_lineno-$LINENO}: looking for aux files: $ac_aux_files" >&5 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in $ac_aux_dir_candidates do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac as_found=: printf "%s\n" "$as_me:${as_lineno-$LINENO}: trying $as_dir" >&5 ac_aux_dir_found=yes ac_install_sh= for ac_aux in $ac_aux_files do # As a special case, if "install-sh" is required, that requirement # can be satisfied by any of "install-sh", "install.sh", or "shtool", # and $ac_install_sh is set appropriately for whichever one is found. if test x"$ac_aux" = x"install-sh" then if test -f "${as_dir}install-sh"; then printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}install-sh found" >&5 ac_install_sh="${as_dir}install-sh -c" elif test -f "${as_dir}install.sh"; then printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}install.sh found" >&5 ac_install_sh="${as_dir}install.sh -c" elif test -f "${as_dir}shtool"; then printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}shtool found" >&5 ac_install_sh="${as_dir}shtool install -c" else ac_aux_dir_found=no if $ac_first_candidate; then ac_missing_aux_files="${ac_missing_aux_files} install-sh" else break fi fi else if test -f "${as_dir}${ac_aux}"; then printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}${ac_aux} found" >&5 else ac_aux_dir_found=no if $ac_first_candidate; then ac_missing_aux_files="${ac_missing_aux_files} ${ac_aux}" else break fi fi fi done if test "$ac_aux_dir_found" = yes; then ac_aux_dir="$as_dir" break fi ac_first_candidate=false as_found=false done IFS=$as_save_IFS if $as_found then : else $as_nop as_fn_error $? "cannot find required auxiliary files:$ac_missing_aux_files" "$LINENO" 5 fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. if test -f "${ac_aux_dir}config.guess"; then ac_config_guess="$SHELL ${ac_aux_dir}config.guess" fi if test -f "${ac_aux_dir}config.sub"; then ac_config_sub="$SHELL ${ac_aux_dir}config.sub" fi if test -f "$ac_aux_dir/configure"; then ac_configure="$SHELL ${ac_aux_dir}configure" fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 printf "%s\n" "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 printf "%s\n" "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 printf "%s\n" "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 printf "%s\n" "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 printf "%s\n" "$as_me: former value: \`$ac_old_val'" >&2;} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 printf "%s\n" "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`printf "%s\n" "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 printf "%s\n" "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`${MAKE-make} distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu am__api_version='1.16' # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. # Reject install programs that cannot install multiple files. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 printf %s "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if test ${ac_cv_path_install+y} then : printf %s "(cached) " >&6 else $as_nop as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac # Account for fact that we put trailing slashes in our PATH walk. case $as_dir in #(( ./ | /[cC]/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_prog$ac_exec_ext"; then if test $ac_prog = install && grep dspmsg "$as_dir$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else rm -rf conftest.one conftest.two conftest.dir echo one > conftest.one echo two > conftest.two mkdir conftest.dir if "$as_dir$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir/" && test -s conftest.one && test -s conftest.two && test -s conftest.dir/conftest.one && test -s conftest.dir/conftest.two then ac_cv_path_install="$as_dir$ac_prog$ac_exec_ext -c" break 3 fi fi fi done done ;; esac done IFS=$as_save_IFS rm -rf conftest.one conftest.two conftest.dir fi if test ${ac_cv_path_install+y}; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 printf "%s\n" "$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 printf %s "checking whether build environment is sane... " >&6; } # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[\\\"\#\$\&\'\`$am_lf]*) as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; esac case $srcdir in *[\\\"\#\$\&\'\`$am_lf\ \ ]*) as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; esac # Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( am_has_slept=no for am_try in 1 2; do echo "timestamp, slept: $am_has_slept" > conftest.file set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$*" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi if test "$*" != "X $srcdir/configure conftest.file" \ && test "$*" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". as_fn_error $? "ls -t appears to fail. Make sure there is not a broken alias in your environment" "$LINENO" 5 fi if test "$2" = conftest.file || test $am_try -eq 2; then break fi # Just in case. sleep 1 am_has_slept=yes done test "$2" = conftest.file ) then # Ok. : else as_fn_error $? "newly created file is older than distributed files! Check your system clock" "$LINENO" 5 fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= if grep 'slept: no' conftest.file >/dev/null 2>&1; then ( sleep 1 ) & am_sleep_pid=$! fi rm -f conftest.file test "$program_prefix" != NONE && program_transform_name="s&^&$program_prefix&;$program_transform_name" # Use a double $ so make ignores it. test "$program_suffix" != NONE && program_transform_name="s&\$&$program_suffix&;$program_transform_name" # Double any \ or $. # By default was `s,x,x', remove it if useless. ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' program_transform_name=`printf "%s\n" "$program_transform_name" | sed "$ac_script"` # Expand $ac_aux_dir to an absolute path. am_aux_dir=`cd "$ac_aux_dir" && pwd` if test x"${MISSING+set}" != xset; then MISSING="\${SHELL} '$am_aux_dir/missing'" fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then am_missing_run="$MISSING " else am_missing_run= { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 printf "%s\n" "$as_me: WARNING: 'missing' script is too old or missing" >&2;} fi if test x"${install_sh+set}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi # Installed binaries are usually stripped using 'strip' when the user # run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the 'STRIP' environment variable to overrule this program. if test "$cross_compiling" != no; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_STRIP+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 printf "%s\n" "$STRIP" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_STRIP+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 printf "%s\n" "$ac_ct_STRIP" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a race-free mkdir -p" >&5 printf %s "checking for a race-free mkdir -p... " >&6; } if test -z "$MKDIR_P"; then if test ${ac_cv_path_mkdir+y} then : printf %s "(cached) " >&6 else $as_nop as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_prog in mkdir gmkdir; do for ac_exec_ext in '' $ac_executable_extensions; do as_fn_executable_p "$as_dir$ac_prog$ac_exec_ext" || continue case `"$as_dir$ac_prog$ac_exec_ext" --version 2>&1` in #( 'mkdir ('*'coreutils) '* | \ 'BusyBox '* | \ 'mkdir (fileutils) '4.1*) ac_cv_path_mkdir=$as_dir$ac_prog$ac_exec_ext break 3;; esac done done done IFS=$as_save_IFS fi test -d ./--version && rmdir ./--version if test ${ac_cv_path_mkdir+y}; then MKDIR_P="$ac_cv_path_mkdir -p" else # As a last resort, use the slow shell script. Don't cache a # value for MKDIR_P within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. MKDIR_P="$ac_install_sh -d" fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 printf "%s\n" "$MKDIR_P" >&6; } for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_AWK+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_AWK="$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 printf "%s\n" "$AWK" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$AWK" && break done { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 printf %s "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`printf "%s\n" "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if eval test \${ac_cv_prog_make_${ac_make}_set+y} then : printf %s "(cached) " >&6 else $as_nop cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } SET_MAKE= else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null # Check whether --enable-silent-rules was given. if test ${enable_silent_rules+y} then : enableval=$enable_silent_rules; fi case $enable_silent_rules in # ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=1;; esac am_make=${MAKE-make} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 printf %s "checking whether $am_make supports nested variables... " >&6; } if test ${am_cv_make_support_nested_variables+y} then : printf %s "(cached) " >&6 else $as_nop if printf "%s\n" 'TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 printf "%s\n" "$am_cv_make_support_nested_variables" >&6; } if test $am_cv_make_support_nested_variables = yes; then AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AM_BACKSLASH='\' if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." am__isrc=' -I$(srcdir)' # test to see if srcdir already configured if test -f $srcdir/config.status; then as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi # Define the identity of the package. PACKAGE='geany' VERSION='2.0' printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h printf "%s\n" "#define VERSION \"$VERSION\"" >>confdefs.h # Some tools Automake needs. ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: # # mkdir_p='$(MKDIR_P)' # We need awk for the "check" target (and possibly the TAP driver). The # system "awk" is bad on some platforms. # Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AMTAR='$${TAR-tar}' # We'll loop over all known methods to create a tar archive until one works. _am_tools='gnutar pax cpio none' am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' # Variables for tags utilities; see am/tags.am if test -z "$CTAGS"; then CTAGS=ctags fi if test -z "$ETAGS"; then ETAGS=etags fi if test -z "$CSCOPE"; then CSCOPE=cscope fi # POSIX will say in a future version that running "rm -f" with no argument # is OK; and we want to be able to make that assumption in our Makefile # recipes. So use an aggressive probe to check that the usage we want is # actually supported "in the wild" to an acceptable degree. # See automake bug#10828. # To make any issue more visible, cause the running configure to be aborted # by default if the 'rm' program in use doesn't match our expectations; the # user can still override this though. if rm -f && rm -fr && rm -rf; then : OK; else cat >&2 <<'END' Oops! Your 'rm' program seems unable to run without file operands specified on the command line, even when the '-f' option is present. This is contrary to the behaviour of most rm programs out there, and not conforming with the upcoming POSIX standard: Please tell bug-automake@gnu.org about your system, including the value of your $PATH and any error possibly output before this message. This can help us improve future automake versions. END if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then echo 'Configuration will proceed anyway, since you have set the' >&2 echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 echo >&2 else cat >&2 <<'END' Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM to "yes", and re-run configure. END as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 fi fi ac_config_headers="$ac_config_headers config.h" # Silence "AC_LINK_IFELSE before AC_USE_SYSTEM_EXTENSIONS" warnings # Note: Enables _GNU_SOURCE on Linux DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depfiles" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} supports the include directive" >&5 printf %s "checking whether ${MAKE-make} supports the include directive... " >&6; } cat > confinc.mk << 'END' am__doit: @echo this is the am__doit target >confinc.out .PHONY: am__doit END am__include="#" am__quote= # BSD make does it like this. echo '.include "confinc.mk" # ignored' > confmf.BSD # Other make implementations (GNU, Solaris 10, AIX) do it like this. echo 'include confinc.mk # ignored' > confmf.GNU _am_result=no for s in GNU BSD; do { echo "$as_me:$LINENO: ${MAKE-make} -f confmf.$s && cat confinc.out" >&5 (${MAKE-make} -f confmf.$s && cat confinc.out) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } case $?:`cat confinc.out 2>/dev/null` in #( '0:this is the am__doit target') : case $s in #( BSD) : am__include='.include' am__quote='"' ;; #( *) : am__include='include' am__quote='' ;; esac ;; #( *) : ;; esac if test "$am__include" != "#"; then _am_result="yes ($s style)" break fi done rm -f confinc.* confmf.* { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ${_am_result}" >&5 printf "%s\n" "${_am_result}" >&6; } # Check whether --enable-dependency-tracking was given. if test ${enable_dependency_tracking+y} then : enableval=$enable_dependency_tracking; fi if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi if test "x$enable_dependency_tracking" != xno; then AMDEP_TRUE= AMDEP_FALSE='#' else AMDEP_TRUE='#' AMDEP_FALSE= fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 printf "%s\n" "$ac_ct_CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then if test "$as_dir$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 printf "%s\n" "$ac_ct_CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}clang", so it can be a program name with args. set dummy ${ac_tool_prefix}clang; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}clang" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "clang", so it can be a program name with args. set dummy clang; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="clang" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 printf "%s\n" "$ac_ct_CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi fi test -z "$CC" && { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion -version; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 printf %s "checking whether the C compiler works... " >&6; } ac_link_default=`printf "%s\n" "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { { ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test ${ac_cv_exeext+y} && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else $as_nop ac_file='' fi if test -z "$ac_file" then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C compiler cannot create executables See \`config.log' for more details" "$LINENO" 5; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 printf %s "checking for C compiler default output file name... " >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 printf "%s\n" "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 printf %s "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else $as_nop { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 printf "%s\n" "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main (void) { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 printf %s "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5; } fi fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 printf "%s\n" "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 printf %s "checking for suffix of object files... " >&6; } if test ${ac_cv_objext+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_nop printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 printf "%s\n" "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports GNU C" >&5 printf %s "checking whether the compiler supports GNU C... " >&6; } if test ${ac_cv_c_compiler_gnu+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_compiler_gnu=yes else $as_nop ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 printf "%s\n" "$ac_cv_c_compiler_gnu" >&6; } ac_compiler_gnu=$ac_cv_c_compiler_gnu if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+y} ac_save_CFLAGS=$CFLAGS { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 printf %s "checking whether $CC accepts -g... " >&6; } if test ${ac_cv_prog_cc_g+y} then : printf %s "(cached) " >&6 else $as_nop ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_g=yes else $as_nop CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : else $as_nop ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 printf "%s\n" "$ac_cv_prog_cc_g" >&6; } if test $ac_test_CFLAGS; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi ac_prog_cc_stdc=no if test x$ac_prog_cc_stdc = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C11 features" >&5 printf %s "checking for $CC option to enable C11 features... " >&6; } if test ${ac_cv_prog_cc_c11+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_prog_cc_c11=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_c_conftest_c11_program _ACEOF for ac_arg in '' -std=gnu11 do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_c11=$ac_arg fi rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cc_c11" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi if test "x$ac_cv_prog_cc_c11" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } else $as_nop if test "x$ac_cv_prog_cc_c11" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c11" >&5 printf "%s\n" "$ac_cv_prog_cc_c11" >&6; } CC="$CC $ac_cv_prog_cc_c11" fi ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c11 ac_prog_cc_stdc=c11 fi fi if test x$ac_prog_cc_stdc = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C99 features" >&5 printf %s "checking for $CC option to enable C99 features... " >&6; } if test ${ac_cv_prog_cc_c99+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_prog_cc_c99=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_c_conftest_c99_program _ACEOF for ac_arg in '' -std=gnu99 -std=c99 -c99 -qlanglvl=extc1x -qlanglvl=extc99 -AC99 -D_STDC_C99= do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_c99=$ac_arg fi rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cc_c99" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi if test "x$ac_cv_prog_cc_c99" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } else $as_nop if test "x$ac_cv_prog_cc_c99" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5 printf "%s\n" "$ac_cv_prog_cc_c99" >&6; } CC="$CC $ac_cv_prog_cc_c99" fi ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99 ac_prog_cc_stdc=c99 fi fi if test x$ac_prog_cc_stdc = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C89 features" >&5 printf %s "checking for $CC option to enable C89 features... " >&6; } if test ${ac_cv_prog_cc_c89+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_c_conftest_c89_program _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi if test "x$ac_cv_prog_cc_c89" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } else $as_nop if test "x$ac_cv_prog_cc_c89" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 printf "%s\n" "$ac_cv_prog_cc_c89" >&6; } CC="$CC $ac_cv_prog_cc_c89" fi ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89 ac_prog_cc_stdc=c89 fi fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 printf %s "checking whether $CC understands -c and -o together... " >&6; } if test ${am_cv_prog_cc_c_o+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF # Make sure it works both with $CC and with simple cc. # Following AC_PROG_CC_C_O, we do the test twice because some # compilers refuse to overwrite an existing .o file with -o, # though they will create one. am_cv_prog_cc_c_o=yes for am_i in 1 2; do if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } \ && test -f conftest2.$ac_objext; then : OK else am_cv_prog_cc_c_o=no break fi done rm -f core conftest* unset am_i fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 printf "%s\n" "$am_cv_prog_cc_c_o" >&6; } if test "$am_cv_prog_cc_c_o" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu depcc="$CC" am_compiler_list= { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 printf %s "checking dependency style of $depcc... " >&6; } if test ${am_cv_CC_dependencies_compiler_type+y} then : printf %s "(cached) " >&6 else $as_nop if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CC_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 printf "%s\n" "$am_cv_CC_dependencies_compiler_type" >&6; } CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= fi ac_header= ac_cache= for ac_item in $ac_header_c_list do if test $ac_cache; then ac_fn_c_check_header_compile "$LINENO" $ac_header ac_cv_header_$ac_cache "$ac_includes_default" if eval test \"x\$ac_cv_header_$ac_cache\" = xyes; then printf "%s\n" "#define $ac_item 1" >> confdefs.h fi ac_header= ac_cache= elif test $ac_header; then ac_cache=$ac_item else ac_header=$ac_item fi done if test $ac_cv_header_stdlib_h = yes && test $ac_cv_header_string_h = yes then : printf "%s\n" "#define STDC_HEADERS 1" >>confdefs.h fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether it is safe to define __EXTENSIONS__" >&5 printf %s "checking whether it is safe to define __EXTENSIONS__... " >&6; } if test ${ac_cv_safe_to_define___extensions__+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ # define __EXTENSIONS__ 1 $ac_includes_default int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_cv_safe_to_define___extensions__=yes else $as_nop ac_cv_safe_to_define___extensions__=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_safe_to_define___extensions__" >&5 printf "%s\n" "$ac_cv_safe_to_define___extensions__" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether _XOPEN_SOURCE should be defined" >&5 printf %s "checking whether _XOPEN_SOURCE should be defined... " >&6; } if test ${ac_cv_should_define__xopen_source+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_should_define__xopen_source=no if test $ac_cv_header_wchar_h = yes then : cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include mbstate_t x; int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #define _XOPEN_SOURCE 500 #include mbstate_t x; int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_cv_should_define__xopen_source=yes fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_should_define__xopen_source" >&5 printf "%s\n" "$ac_cv_should_define__xopen_source" >&6; } printf "%s\n" "#define _ALL_SOURCE 1" >>confdefs.h printf "%s\n" "#define _DARWIN_C_SOURCE 1" >>confdefs.h printf "%s\n" "#define _GNU_SOURCE 1" >>confdefs.h printf "%s\n" "#define _HPUX_ALT_XOPEN_SOCKET_API 1" >>confdefs.h printf "%s\n" "#define _NETBSD_SOURCE 1" >>confdefs.h printf "%s\n" "#define _OPENBSD_SOURCE 1" >>confdefs.h printf "%s\n" "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h printf "%s\n" "#define __STDC_WANT_IEC_60559_ATTRIBS_EXT__ 1" >>confdefs.h printf "%s\n" "#define __STDC_WANT_IEC_60559_BFP_EXT__ 1" >>confdefs.h printf "%s\n" "#define __STDC_WANT_IEC_60559_DFP_EXT__ 1" >>confdefs.h printf "%s\n" "#define __STDC_WANT_IEC_60559_FUNCS_EXT__ 1" >>confdefs.h printf "%s\n" "#define __STDC_WANT_IEC_60559_TYPES_EXT__ 1" >>confdefs.h printf "%s\n" "#define __STDC_WANT_LIB_EXT2__ 1" >>confdefs.h printf "%s\n" "#define __STDC_WANT_MATH_SPEC_FUNCS__ 1" >>confdefs.h printf "%s\n" "#define _TANDEM_SOURCE 1" >>confdefs.h if test $ac_cv_header_minix_config_h = yes then : MINIX=yes printf "%s\n" "#define _MINIX 1" >>confdefs.h printf "%s\n" "#define _POSIX_SOURCE 1" >>confdefs.h printf "%s\n" "#define _POSIX_1_SOURCE 2" >>confdefs.h else $as_nop MINIX= fi if test $ac_cv_safe_to_define___extensions__ = yes then : printf "%s\n" "#define __EXTENSIONS__ 1" >>confdefs.h fi if test $ac_cv_should_define__xopen_source = yes then : printf "%s\n" "#define _XOPEN_SOURCE 500" >>confdefs.h fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 printf %s "checking for a sed that does not truncate output... " >&6; } if test ${ac_cv_path_SED+y} then : printf %s "(cached) " >&6 else $as_nop ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ for ac_i in 1 2 3 4 5 6 7; do ac_script="$ac_script$as_nl$ac_script" done echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed { ac_script=; unset ac_script;} if test -z "$SED"; then ac_path_SED_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_prog in sed gsed do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_SED="$as_dir$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_SED" || continue # Check for GNU ac_path_SED and select it if it is found. # Check for GNU $ac_path_SED case `"$ac_path_SED" --version 2>&1` in *GNU*) ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; *) ac_count=0 printf %s 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" printf "%s\n" '' >> "conftest.nl" "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_SED_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_SED="$ac_path_SED" ac_path_SED_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_SED_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_SED"; then as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 fi else ac_cv_path_SED=$SED fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 printf "%s\n" "$ac_cv_path_SED" >&6; } SED="$ac_cv_path_SED" rm -f conftest.sed { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether NLS is requested" >&5 printf %s "checking whether NLS is requested... " >&6; } # Check whether --enable-nls was given. if test ${enable_nls+y} then : enableval=$enable_nls; USE_NLS=$enableval else $as_nop USE_NLS=yes fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $USE_NLS" >&5 printf "%s\n" "$USE_NLS" >&6; } GETTEXT_MACRO_VERSION=0.19 # Prepare PATH_SEPARATOR. # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then # Determine PATH_SEPARATOR by trying to find /bin/sh in a PATH which # contains only /bin. Note that ksh looks also at the FPATH variable, # so we have to set that as well for the test. PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ || PATH_SEPARATOR=';' } fi # Find out how to test for executable files. Don't use a zero-byte file, # as systems may use methods other than mode bits to determine executability. cat >conf$$.file <<_ASEOF #! /bin/sh exit 0 _ASEOF chmod +x conf$$.file if test -x conf$$.file >/dev/null 2>&1; then ac_executable_p="test -x" else ac_executable_p="test -f" fi rm -f conf$$.file # Extract the first word of "msgfmt", so it can be a program name with args. set dummy msgfmt; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_path_MSGFMT+y} then : printf %s "(cached) " >&6 else $as_nop case "$MSGFMT" in [\\/]* | ?:[\\/]*) ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path. ;; *) ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS="$ac_save_IFS" test -z "$ac_dir" && ac_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then echo "$as_me: trying $ac_dir/$ac_word..." >&5 if $ac_dir/$ac_word --statistics /dev/null >&5 2>&1 && (if $ac_dir/$ac_word --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then ac_cv_path_MSGFMT="$ac_dir/$ac_word$ac_exec_ext" break 2 fi fi done done IFS="$ac_save_IFS" test -z "$ac_cv_path_MSGFMT" && ac_cv_path_MSGFMT=":" ;; esac fi MSGFMT="$ac_cv_path_MSGFMT" if test "$MSGFMT" != ":"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MSGFMT" >&5 printf "%s\n" "$MSGFMT" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi # Extract the first word of "gmsgfmt", so it can be a program name with args. set dummy gmsgfmt; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_path_GMSGFMT+y} then : printf %s "(cached) " >&6 else $as_nop case $GMSGFMT in [\\/]* | ?:[\\/]*) ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_path_GMSGFMT="$as_dir$ac_word$ac_exec_ext" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="$MSGFMT" ;; esac fi GMSGFMT=$ac_cv_path_GMSGFMT if test -n "$GMSGFMT"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $GMSGFMT" >&5 printf "%s\n" "$GMSGFMT" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi case `$MSGFMT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) MSGFMT_015=: ;; *) MSGFMT_015=$MSGFMT ;; esac case `$GMSGFMT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) GMSGFMT_015=: ;; *) GMSGFMT_015=$GMSGFMT ;; esac # Prepare PATH_SEPARATOR. # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then # Determine PATH_SEPARATOR by trying to find /bin/sh in a PATH which # contains only /bin. Note that ksh looks also at the FPATH variable, # so we have to set that as well for the test. PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ || PATH_SEPARATOR=';' } fi # Find out how to test for executable files. Don't use a zero-byte file, # as systems may use methods other than mode bits to determine executability. cat >conf$$.file <<_ASEOF #! /bin/sh exit 0 _ASEOF chmod +x conf$$.file if test -x conf$$.file >/dev/null 2>&1; then ac_executable_p="test -x" else ac_executable_p="test -f" fi rm -f conf$$.file # Extract the first word of "xgettext", so it can be a program name with args. set dummy xgettext; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_path_XGETTEXT+y} then : printf %s "(cached) " >&6 else $as_nop case "$XGETTEXT" in [\\/]* | ?:[\\/]*) ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path. ;; *) ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS="$ac_save_IFS" test -z "$ac_dir" && ac_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then echo "$as_me: trying $ac_dir/$ac_word..." >&5 if $ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null >&5 2>&1 && (if $ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then ac_cv_path_XGETTEXT="$ac_dir/$ac_word$ac_exec_ext" break 2 fi fi done done IFS="$ac_save_IFS" test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT=":" ;; esac fi XGETTEXT="$ac_cv_path_XGETTEXT" if test "$XGETTEXT" != ":"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $XGETTEXT" >&5 printf "%s\n" "$XGETTEXT" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi rm -f messages.po case `$XGETTEXT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) XGETTEXT_015=: ;; *) XGETTEXT_015=$XGETTEXT ;; esac # Prepare PATH_SEPARATOR. # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then # Determine PATH_SEPARATOR by trying to find /bin/sh in a PATH which # contains only /bin. Note that ksh looks also at the FPATH variable, # so we have to set that as well for the test. PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ || PATH_SEPARATOR=';' } fi # Find out how to test for executable files. Don't use a zero-byte file, # as systems may use methods other than mode bits to determine executability. cat >conf$$.file <<_ASEOF #! /bin/sh exit 0 _ASEOF chmod +x conf$$.file if test -x conf$$.file >/dev/null 2>&1; then ac_executable_p="test -x" else ac_executable_p="test -f" fi rm -f conf$$.file # Extract the first word of "msgmerge", so it can be a program name with args. set dummy msgmerge; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_path_MSGMERGE+y} then : printf %s "(cached) " >&6 else $as_nop case "$MSGMERGE" in [\\/]* | ?:[\\/]*) ac_cv_path_MSGMERGE="$MSGMERGE" # Let the user override the test with a path. ;; *) ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS="$ac_save_IFS" test -z "$ac_dir" && ac_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then echo "$as_me: trying $ac_dir/$ac_word..." >&5 if $ac_dir/$ac_word --update -q /dev/null /dev/null >&5 2>&1; then ac_cv_path_MSGMERGE="$ac_dir/$ac_word$ac_exec_ext" break 2 fi fi done done IFS="$ac_save_IFS" test -z "$ac_cv_path_MSGMERGE" && ac_cv_path_MSGMERGE=":" ;; esac fi MSGMERGE="$ac_cv_path_MSGMERGE" if test "$MSGMERGE" != ":"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MSGMERGE" >&5 printf "%s\n" "$MSGMERGE" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$localedir" || localedir='${datadir}/locale' test -n "${XGETTEXT_EXTRA_OPTIONS+set}" || XGETTEXT_EXTRA_OPTIONS= ac_config_commands="$ac_config_commands po-directories" if test "X$prefix" = "XNONE"; then acl_final_prefix="$ac_default_prefix" else acl_final_prefix="$prefix" fi if test "X$exec_prefix" = "XNONE"; then acl_final_exec_prefix='${prefix}' else acl_final_exec_prefix="$exec_prefix" fi acl_save_prefix="$prefix" prefix="$acl_final_prefix" eval acl_final_exec_prefix=\"$acl_final_exec_prefix\" prefix="$acl_save_prefix" # Make sure we can run config.sub. $SHELL "${ac_aux_dir}config.sub" sun4 >/dev/null 2>&1 || as_fn_error $? "cannot run $SHELL ${ac_aux_dir}config.sub" "$LINENO" 5 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 printf %s "checking build system type... " >&6; } if test ${ac_cv_build+y} then : printf %s "(cached) " >&6 else $as_nop ac_build_alias=$build_alias test "x$ac_build_alias" = x && ac_build_alias=`$SHELL "${ac_aux_dir}config.guess"` test "x$ac_build_alias" = x && as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 ac_cv_build=`$SHELL "${ac_aux_dir}config.sub" $ac_build_alias` || as_fn_error $? "$SHELL ${ac_aux_dir}config.sub $ac_build_alias failed" "$LINENO" 5 fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 printf "%s\n" "$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; *) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; esac build=$ac_cv_build ac_save_IFS=$IFS; IFS='-' set x $ac_cv_build shift build_cpu=$1 build_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: build_os=$* IFS=$ac_save_IFS case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 printf %s "checking host system type... " >&6; } if test ${ac_cv_host+y} then : printf %s "(cached) " >&6 else $as_nop if test "x$host_alias" = x; then ac_cv_host=$ac_cv_build else ac_cv_host=`$SHELL "${ac_aux_dir}config.sub" $host_alias` || as_fn_error $? "$SHELL ${ac_aux_dir}config.sub $host_alias failed" "$LINENO" 5 fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 printf "%s\n" "$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; *) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; esac host=$ac_cv_host ac_save_IFS=$IFS; IFS='-' set x $ac_cv_host shift host_cpu=$1 host_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: host_os=$* IFS=$ac_save_IFS case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac # Check whether --with-gnu-ld was given. if test ${with_gnu_ld+y} then : withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes else $as_nop with_gnu_ld=no fi # Prepare PATH_SEPARATOR. # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then # Determine PATH_SEPARATOR by trying to find /bin/sh in a PATH which # contains only /bin. Note that ksh looks also at the FPATH variable, # so we have to set that as well for the test. PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ || PATH_SEPARATOR=';' } fi ac_prog=ld if test "$GCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 printf %s "checking for ld used by $CC... " >&6; } case $host in *-*-mingw*) # gcc leaves a trailing carriage return which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [\\/]* | ?:[\\/]*) re_direlt='/[^/][^/]*/\.\./' # Canonicalize the pathname of ld ac_prog=`echo "$ac_prog"| sed 's%\\\\%/%g'` while echo "$ac_prog" | grep "$re_direlt" > /dev/null 2>&1; do ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` done test -z "$LD" && LD="$ac_prog" ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test "$with_gnu_ld" = yes; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 printf %s "checking for GNU ld... " >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 printf %s "checking for non-GNU ld... " >&6; } fi if test ${acl_cv_path_LD+y} then : printf %s "(cached) " >&6 else $as_nop if test -z "$LD"; then acl_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS="$acl_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then acl_cv_path_LD="$ac_dir/$ac_prog" # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$acl_cv_path_LD" -v 2>&1 &5 printf "%s\n" "$LD" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 printf %s "checking if the linker ($LD) is GNU ld... " >&6; } if test ${acl_cv_prog_gnu_ld+y} then : printf %s "(cached) " >&6 else $as_nop # I'd rather use --version here, but apparently some GNU lds only accept -v. case `$LD -v 2>&1 &5 printf "%s\n" "$acl_cv_prog_gnu_ld" >&6; } with_gnu_ld=$acl_cv_prog_gnu_ld { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for shared library run path origin" >&5 printf %s "checking for shared library run path origin... " >&6; } if test ${acl_cv_rpath+y} then : printf %s "(cached) " >&6 else $as_nop CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS" LD="$LD" with_gnu_ld="$with_gnu_ld" \ ${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" > conftest.sh . ./conftest.sh rm -f ./conftest.sh acl_cv_rpath=done fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $acl_cv_rpath" >&5 printf "%s\n" "$acl_cv_rpath" >&6; } wl="$acl_cv_wl" acl_libext="$acl_cv_libext" acl_shlibext="$acl_cv_shlibext" acl_libname_spec="$acl_cv_libname_spec" acl_library_names_spec="$acl_cv_library_names_spec" acl_hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec" acl_hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator" acl_hardcode_direct="$acl_cv_hardcode_direct" acl_hardcode_minus_L="$acl_cv_hardcode_minus_L" # Check whether --enable-rpath was given. if test ${enable_rpath+y} then : enableval=$enable_rpath; : else $as_nop enable_rpath=yes fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 printf %s "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if test ${ac_cv_prog_CPP+y} then : printf %s "(cached) " >&6 else $as_nop # Double quotes because $CC needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" cpp /lib/cpp do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO" then : else $as_nop # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO" then : # Broken: success on invalid input. continue else $as_nop # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok then : break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 printf "%s\n" "$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO" then : else $as_nop # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO" then : # Broken: success on invalid input. continue else $as_nop # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok then : else $as_nop { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 printf %s "checking for grep that handles long lines and -e... " >&6; } if test ${ac_cv_path_GREP+y} then : printf %s "(cached) " >&6 else $as_nop if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_prog in grep ggrep do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_GREP" || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 printf %s 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" printf "%s\n" 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 printf "%s\n" "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 printf %s "checking for egrep... " >&6; } if test ${ac_cv_path_EGREP+y} then : printf %s "(cached) " >&6 else $as_nop if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_prog in egrep do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_EGREP" || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 printf %s 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" printf "%s\n" 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP fi fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 printf "%s\n" "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" acl_libdirstem=lib acl_libdirstem2= case "$host_os" in solaris*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for 64-bit host" >&5 printf %s "checking for 64-bit host... " >&6; } if test ${gl_cv_solaris_64bit+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef _LP64 sixtyfour bits #endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "sixtyfour bits" >/dev/null 2>&1 then : gl_cv_solaris_64bit=yes else $as_nop gl_cv_solaris_64bit=no fi rm -rf conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $gl_cv_solaris_64bit" >&5 printf "%s\n" "$gl_cv_solaris_64bit" >&6; } if test $gl_cv_solaris_64bit = yes; then acl_libdirstem=lib/64 case "$host_cpu" in sparc*) acl_libdirstem2=lib/sparcv9 ;; i*86 | x86_64) acl_libdirstem2=lib/amd64 ;; esac fi ;; *) searchpath=`(LC_ALL=C $CC -print-search-dirs) 2>/dev/null | sed -n -e 's,^libraries: ,,p' | sed -e 's,^=,,'` if test -n "$searchpath"; then acl_save_IFS="${IFS= }"; IFS=":" for searchdir in $searchpath; do if test -d "$searchdir"; then case "$searchdir" in */lib64/ | */lib64 ) acl_libdirstem=lib64 ;; */../ | */.. ) # Better ignore directories of this form. They are misleading. ;; *) searchdir=`cd "$searchdir" && pwd` case "$searchdir" in */lib64 ) acl_libdirstem=lib64 ;; esac ;; esac fi done IFS="$acl_save_IFS" fi ;; esac test -n "$acl_libdirstem2" || acl_libdirstem2="$acl_libdirstem" use_additional=yes acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval additional_includedir=\"$includedir\" eval additional_libdir=\"$libdir\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" # Check whether --with-libiconv-prefix was given. if test ${with_libiconv_prefix+y} then : withval=$with_libiconv_prefix; if test "X$withval" = "Xno"; then use_additional=no else if test "X$withval" = "X"; then acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval additional_includedir=\"$includedir\" eval additional_libdir=\"$libdir\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" else additional_includedir="$withval/include" additional_libdir="$withval/$acl_libdirstem" if test "$acl_libdirstem2" != "$acl_libdirstem" \ && ! test -d "$withval/$acl_libdirstem"; then additional_libdir="$withval/$acl_libdirstem2" fi fi fi fi LIBICONV= LTLIBICONV= INCICONV= LIBICONV_PREFIX= HAVE_LIBICONV= rpathdirs= ltrpathdirs= names_already_handled= names_next_round='iconv ' while test -n "$names_next_round"; do names_this_round="$names_next_round" names_next_round= for name in $names_this_round; do already_handled= for n in $names_already_handled; do if test "$n" = "$name"; then already_handled=yes break fi done if test -z "$already_handled"; then names_already_handled="$names_already_handled $name" uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./+-|ABCDEFGHIJKLMNOPQRSTUVWXYZ____|'` eval value=\"\$HAVE_LIB$uppername\" if test -n "$value"; then if test "$value" = yes; then eval value=\"\$LIB$uppername\" test -z "$value" || LIBICONV="${LIBICONV}${LIBICONV:+ }$value" eval value=\"\$LTLIB$uppername\" test -z "$value" || LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }$value" else : fi else found_dir= found_la= found_so= found_a= eval libname=\"$acl_libname_spec\" # typically: libname=lib$name if test -n "$acl_shlibext"; then shrext=".$acl_shlibext" # typically: shrext=.so else shrext= fi if test $use_additional = yes; then dir="$additional_libdir" if test -n "$acl_shlibext"; then if test -f "$dir/$libname$shrext"; then found_dir="$dir" found_so="$dir/$libname$shrext" else if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then ver=`(cd "$dir" && \ for f in "$libname$shrext".*; do echo "$f"; done \ | sed -e "s,^$libname$shrext\\\\.,," \ | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ | sed 1q ) 2>/dev/null` if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then found_dir="$dir" found_so="$dir/$libname$shrext.$ver" fi else eval library_names=\"$acl_library_names_spec\" for f in $library_names; do if test -f "$dir/$f"; then found_dir="$dir" found_so="$dir/$f" break fi done fi fi fi if test "X$found_dir" = "X"; then if test -f "$dir/$libname.$acl_libext"; then found_dir="$dir" found_a="$dir/$libname.$acl_libext" fi fi if test "X$found_dir" != "X"; then if test -f "$dir/$libname.la"; then found_la="$dir/$libname.la" fi fi fi if test "X$found_dir" = "X"; then for x in $LDFLAGS $LTLIBICONV; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" case "$x" in -L*) dir=`echo "X$x" | sed -e 's/^X-L//'` if test -n "$acl_shlibext"; then if test -f "$dir/$libname$shrext"; then found_dir="$dir" found_so="$dir/$libname$shrext" else if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then ver=`(cd "$dir" && \ for f in "$libname$shrext".*; do echo "$f"; done \ | sed -e "s,^$libname$shrext\\\\.,," \ | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ | sed 1q ) 2>/dev/null` if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then found_dir="$dir" found_so="$dir/$libname$shrext.$ver" fi else eval library_names=\"$acl_library_names_spec\" for f in $library_names; do if test -f "$dir/$f"; then found_dir="$dir" found_so="$dir/$f" break fi done fi fi fi if test "X$found_dir" = "X"; then if test -f "$dir/$libname.$acl_libext"; then found_dir="$dir" found_a="$dir/$libname.$acl_libext" fi fi if test "X$found_dir" != "X"; then if test -f "$dir/$libname.la"; then found_la="$dir/$libname.la" fi fi ;; esac if test "X$found_dir" != "X"; then break fi done fi if test "X$found_dir" != "X"; then LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-L$found_dir -l$name" if test "X$found_so" != "X"; then if test "$enable_rpath" = no \ || test "X$found_dir" = "X/usr/$acl_libdirstem" \ || test "X$found_dir" = "X/usr/$acl_libdirstem2"; then LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so" else haveit= for x in $ltrpathdirs; do if test "X$x" = "X$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then ltrpathdirs="$ltrpathdirs $found_dir" fi if test "$acl_hardcode_direct" = yes; then LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so" else if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so" haveit= for x in $rpathdirs; do if test "X$x" = "X$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then rpathdirs="$rpathdirs $found_dir" fi else haveit= for x in $LDFLAGS $LIBICONV; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X-L$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then LIBICONV="${LIBICONV}${LIBICONV:+ }-L$found_dir" fi if test "$acl_hardcode_minus_L" != no; then LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so" else LIBICONV="${LIBICONV}${LIBICONV:+ }-l$name" fi fi fi fi else if test "X$found_a" != "X"; then LIBICONV="${LIBICONV}${LIBICONV:+ }$found_a" else LIBICONV="${LIBICONV}${LIBICONV:+ }-L$found_dir -l$name" fi fi additional_includedir= case "$found_dir" in */$acl_libdirstem | */$acl_libdirstem/) basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem/"'*$,,'` if test "$name" = 'iconv'; then LIBICONV_PREFIX="$basedir" fi additional_includedir="$basedir/include" ;; */$acl_libdirstem2 | */$acl_libdirstem2/) basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem2/"'*$,,'` if test "$name" = 'iconv'; then LIBICONV_PREFIX="$basedir" fi additional_includedir="$basedir/include" ;; esac if test "X$additional_includedir" != "X"; then if test "X$additional_includedir" != "X/usr/include"; then haveit= if test "X$additional_includedir" = "X/usr/local/include"; then if test -n "$GCC"; then case $host_os in linux* | gnu* | k*bsd*-gnu) haveit=yes;; esac fi fi if test -z "$haveit"; then for x in $CPPFLAGS $INCICONV; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X-I$additional_includedir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_includedir"; then INCICONV="${INCICONV}${INCICONV:+ }-I$additional_includedir" fi fi fi fi fi if test -n "$found_la"; then save_libdir="$libdir" case "$found_la" in */* | *\\*) . "$found_la" ;; *) . "./$found_la" ;; esac libdir="$save_libdir" for dep in $dependency_libs; do case "$dep" in -L*) additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` if test "X$additional_libdir" != "X/usr/$acl_libdirstem" \ && test "X$additional_libdir" != "X/usr/$acl_libdirstem2"; then haveit= if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem" \ || test "X$additional_libdir" = "X/usr/local/$acl_libdirstem2"; then if test -n "$GCC"; then case $host_os in linux* | gnu* | k*bsd*-gnu) haveit=yes;; esac fi fi if test -z "$haveit"; then haveit= for x in $LDFLAGS $LIBICONV; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X-L$additional_libdir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_libdir"; then LIBICONV="${LIBICONV}${LIBICONV:+ }-L$additional_libdir" fi fi haveit= for x in $LDFLAGS $LTLIBICONV; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X-L$additional_libdir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_libdir"; then LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-L$additional_libdir" fi fi fi fi ;; -R*) dir=`echo "X$dep" | sed -e 's/^X-R//'` if test "$enable_rpath" != no; then haveit= for x in $rpathdirs; do if test "X$x" = "X$dir"; then haveit=yes break fi done if test -z "$haveit"; then rpathdirs="$rpathdirs $dir" fi haveit= for x in $ltrpathdirs; do if test "X$x" = "X$dir"; then haveit=yes break fi done if test -z "$haveit"; then ltrpathdirs="$ltrpathdirs $dir" fi fi ;; -l*) names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` ;; *.la) names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` ;; *) LIBICONV="${LIBICONV}${LIBICONV:+ }$dep" LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }$dep" ;; esac done fi else LIBICONV="${LIBICONV}${LIBICONV:+ }-l$name" LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-l$name" fi fi fi done done if test "X$rpathdirs" != "X"; then if test -n "$acl_hardcode_libdir_separator"; then alldirs= for found_dir in $rpathdirs; do alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$found_dir" done acl_save_libdir="$libdir" libdir="$alldirs" eval flag=\"$acl_hardcode_libdir_flag_spec\" libdir="$acl_save_libdir" LIBICONV="${LIBICONV}${LIBICONV:+ }$flag" else for found_dir in $rpathdirs; do acl_save_libdir="$libdir" libdir="$found_dir" eval flag=\"$acl_hardcode_libdir_flag_spec\" libdir="$acl_save_libdir" LIBICONV="${LIBICONV}${LIBICONV:+ }$flag" done fi fi if test "X$ltrpathdirs" != "X"; then for found_dir in $ltrpathdirs; do LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-R$found_dir" done fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for CFPreferencesCopyAppValue" >&5 printf %s "checking for CFPreferencesCopyAppValue... " >&6; } if test ${gt_cv_func_CFPreferencesCopyAppValue+y} then : printf %s "(cached) " >&6 else $as_nop gt_save_LIBS="$LIBS" LIBS="$LIBS -Wl,-framework -Wl,CoreFoundation" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main (void) { CFPreferencesCopyAppValue(NULL, NULL) ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : gt_cv_func_CFPreferencesCopyAppValue=yes else $as_nop gt_cv_func_CFPreferencesCopyAppValue=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS="$gt_save_LIBS" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $gt_cv_func_CFPreferencesCopyAppValue" >&5 printf "%s\n" "$gt_cv_func_CFPreferencesCopyAppValue" >&6; } if test $gt_cv_func_CFPreferencesCopyAppValue = yes; then printf "%s\n" "#define HAVE_CFPREFERENCESCOPYAPPVALUE 1" >>confdefs.h fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for CFLocaleCopyCurrent" >&5 printf %s "checking for CFLocaleCopyCurrent... " >&6; } if test ${gt_cv_func_CFLocaleCopyCurrent+y} then : printf %s "(cached) " >&6 else $as_nop gt_save_LIBS="$LIBS" LIBS="$LIBS -Wl,-framework -Wl,CoreFoundation" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main (void) { CFLocaleCopyCurrent(); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : gt_cv_func_CFLocaleCopyCurrent=yes else $as_nop gt_cv_func_CFLocaleCopyCurrent=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS="$gt_save_LIBS" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $gt_cv_func_CFLocaleCopyCurrent" >&5 printf "%s\n" "$gt_cv_func_CFLocaleCopyCurrent" >&6; } if test $gt_cv_func_CFLocaleCopyCurrent = yes; then printf "%s\n" "#define HAVE_CFLOCALECOPYCURRENT 1" >>confdefs.h fi INTL_MACOSX_LIBS= if test $gt_cv_func_CFPreferencesCopyAppValue = yes || test $gt_cv_func_CFLocaleCopyCurrent = yes; then INTL_MACOSX_LIBS="-Wl,-framework -Wl,CoreFoundation" fi LIBINTL= LTLIBINTL= POSUB= case " $gt_needs " in *" need-formatstring-macros "*) gt_api_version=3 ;; *" need-ngettext "*) gt_api_version=2 ;; *) gt_api_version=1 ;; esac gt_func_gnugettext_libc="gt_cv_func_gnugettext${gt_api_version}_libc" gt_func_gnugettext_libintl="gt_cv_func_gnugettext${gt_api_version}_libintl" if test "$USE_NLS" = "yes"; then gt_use_preinstalled_gnugettext=no if test $gt_api_version -ge 3; then gt_revision_test_code=' #ifndef __GNU_GETTEXT_SUPPORTED_REVISION #define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1) #endif typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1]; ' else gt_revision_test_code= fi if test $gt_api_version -ge 2; then gt_expression_test_code=' + * ngettext ("", "", 0)' else gt_expression_test_code= fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GNU gettext in libc" >&5 printf %s "checking for GNU gettext in libc... " >&6; } if eval test \${$gt_func_gnugettext_libc+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #ifndef __GNU_GETTEXT_SUPPORTED_REVISION extern int _nl_msg_cat_cntr; extern int *_nl_domain_bindings; #define __GNU_GETTEXT_SYMBOL_EXPRESSION (_nl_msg_cat_cntr + *_nl_domain_bindings) #else #define __GNU_GETTEXT_SYMBOL_EXPRESSION 0 #endif $gt_revision_test_code int main (void) { bindtextdomain ("", ""); return * gettext ("")$gt_expression_test_code + __GNU_GETTEXT_SYMBOL_EXPRESSION ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : eval "$gt_func_gnugettext_libc=yes" else $as_nop eval "$gt_func_gnugettext_libc=no" fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$gt_func_gnugettext_libc { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 printf "%s\n" "$ac_res" >&6; } if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" != "yes"; }; then am_save_CPPFLAGS="$CPPFLAGS" for element in $INCICONV; do haveit= for x in $CPPFLAGS; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X$element"; then haveit=yes break fi done if test -z "$haveit"; then CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }$element" fi done { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for iconv" >&5 printf %s "checking for iconv... " >&6; } if test ${am_cv_func_iconv+y} then : printf %s "(cached) " >&6 else $as_nop am_cv_func_iconv="no, consider installing GNU libiconv" am_cv_lib_iconv=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main (void) { iconv_t cd = iconv_open("",""); iconv(cd,NULL,NULL,NULL,NULL); iconv_close(cd); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : am_cv_func_iconv=yes fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext if test "$am_cv_func_iconv" != yes; then am_save_LIBS="$LIBS" LIBS="$LIBS $LIBICONV" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main (void) { iconv_t cd = iconv_open("",""); iconv(cd,NULL,NULL,NULL,NULL); iconv_close(cd); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : am_cv_lib_iconv=yes am_cv_func_iconv=yes fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS="$am_save_LIBS" fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_func_iconv" >&5 printf "%s\n" "$am_cv_func_iconv" >&6; } if test "$am_cv_func_iconv" = yes; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for working iconv" >&5 printf %s "checking for working iconv... " >&6; } if test ${am_cv_func_iconv_works+y} then : printf %s "(cached) " >&6 else $as_nop am_save_LIBS="$LIBS" if test $am_cv_lib_iconv = yes; then LIBS="$LIBS $LIBICONV" fi am_cv_func_iconv_works=no for ac_iconv_const in '' 'const'; do if test "$cross_compiling" = yes then : case "$host_os" in aix* | hpux*) am_cv_func_iconv_works="guessing no" ;; *) am_cv_func_iconv_works="guessing yes" ;; esac else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #ifndef ICONV_CONST # define ICONV_CONST $ac_iconv_const #endif int main (void) { int result = 0; /* Test against AIX 5.1 bug: Failures are not distinguishable from successful returns. */ { iconv_t cd_utf8_to_88591 = iconv_open ("ISO8859-1", "UTF-8"); if (cd_utf8_to_88591 != (iconv_t)(-1)) { static ICONV_CONST char input[] = "\342\202\254"; /* EURO SIGN */ char buf[10]; ICONV_CONST char *inptr = input; size_t inbytesleft = strlen (input); char *outptr = buf; size_t outbytesleft = sizeof (buf); size_t res = iconv (cd_utf8_to_88591, &inptr, &inbytesleft, &outptr, &outbytesleft); if (res == 0) result |= 1; iconv_close (cd_utf8_to_88591); } } /* Test against Solaris 10 bug: Failures are not distinguishable from successful returns. */ { iconv_t cd_ascii_to_88591 = iconv_open ("ISO8859-1", "646"); if (cd_ascii_to_88591 != (iconv_t)(-1)) { static ICONV_CONST char input[] = "\263"; char buf[10]; ICONV_CONST char *inptr = input; size_t inbytesleft = strlen (input); char *outptr = buf; size_t outbytesleft = sizeof (buf); size_t res = iconv (cd_ascii_to_88591, &inptr, &inbytesleft, &outptr, &outbytesleft); if (res == 0) result |= 2; iconv_close (cd_ascii_to_88591); } } /* Test against AIX 6.1..7.1 bug: Buffer overrun. */ { iconv_t cd_88591_to_utf8 = iconv_open ("UTF-8", "ISO-8859-1"); if (cd_88591_to_utf8 != (iconv_t)(-1)) { static ICONV_CONST char input[] = "\304"; static char buf[2] = { (char)0xDE, (char)0xAD }; ICONV_CONST char *inptr = input; size_t inbytesleft = 1; char *outptr = buf; size_t outbytesleft = 1; size_t res = iconv (cd_88591_to_utf8, &inptr, &inbytesleft, &outptr, &outbytesleft); if (res != (size_t)(-1) || outptr - buf > 1 || buf[1] != (char)0xAD) result |= 4; iconv_close (cd_88591_to_utf8); } } #if 0 /* This bug could be worked around by the caller. */ /* Test against HP-UX 11.11 bug: Positive return value instead of 0. */ { iconv_t cd_88591_to_utf8 = iconv_open ("utf8", "iso88591"); if (cd_88591_to_utf8 != (iconv_t)(-1)) { static ICONV_CONST char input[] = "\304rger mit b\366sen B\374bchen ohne Augenma\337"; char buf[50]; ICONV_CONST char *inptr = input; size_t inbytesleft = strlen (input); char *outptr = buf; size_t outbytesleft = sizeof (buf); size_t res = iconv (cd_88591_to_utf8, &inptr, &inbytesleft, &outptr, &outbytesleft); if ((int)res > 0) result |= 8; iconv_close (cd_88591_to_utf8); } } #endif /* Test against HP-UX 11.11 bug: No converter from EUC-JP to UTF-8 is provided. */ if (/* Try standardized names. */ iconv_open ("UTF-8", "EUC-JP") == (iconv_t)(-1) /* Try IRIX, OSF/1 names. */ && iconv_open ("UTF-8", "eucJP") == (iconv_t)(-1) /* Try AIX names. */ && iconv_open ("UTF-8", "IBM-eucJP") == (iconv_t)(-1) /* Try HP-UX names. */ && iconv_open ("utf8", "eucJP") == (iconv_t)(-1)) result |= 16; return result; ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO" then : am_cv_func_iconv_works=yes fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi test "$am_cv_func_iconv_works" = no || break done LIBS="$am_save_LIBS" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_func_iconv_works" >&5 printf "%s\n" "$am_cv_func_iconv_works" >&6; } case "$am_cv_func_iconv_works" in *no) am_func_iconv=no am_cv_lib_iconv=no ;; *) am_func_iconv=yes ;; esac else am_func_iconv=no am_cv_lib_iconv=no fi if test "$am_func_iconv" = yes; then printf "%s\n" "#define HAVE_ICONV 1" >>confdefs.h fi if test "$am_cv_lib_iconv" = yes; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to link with libiconv" >&5 printf %s "checking how to link with libiconv... " >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $LIBICONV" >&5 printf "%s\n" "$LIBICONV" >&6; } else CPPFLAGS="$am_save_CPPFLAGS" LIBICONV= LTLIBICONV= fi use_additional=yes acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval additional_includedir=\"$includedir\" eval additional_libdir=\"$libdir\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" # Check whether --with-libintl-prefix was given. if test ${with_libintl_prefix+y} then : withval=$with_libintl_prefix; if test "X$withval" = "Xno"; then use_additional=no else if test "X$withval" = "X"; then acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval additional_includedir=\"$includedir\" eval additional_libdir=\"$libdir\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" else additional_includedir="$withval/include" additional_libdir="$withval/$acl_libdirstem" if test "$acl_libdirstem2" != "$acl_libdirstem" \ && ! test -d "$withval/$acl_libdirstem"; then additional_libdir="$withval/$acl_libdirstem2" fi fi fi fi LIBINTL= LTLIBINTL= INCINTL= LIBINTL_PREFIX= HAVE_LIBINTL= rpathdirs= ltrpathdirs= names_already_handled= names_next_round='intl ' while test -n "$names_next_round"; do names_this_round="$names_next_round" names_next_round= for name in $names_this_round; do already_handled= for n in $names_already_handled; do if test "$n" = "$name"; then already_handled=yes break fi done if test -z "$already_handled"; then names_already_handled="$names_already_handled $name" uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./+-|ABCDEFGHIJKLMNOPQRSTUVWXYZ____|'` eval value=\"\$HAVE_LIB$uppername\" if test -n "$value"; then if test "$value" = yes; then eval value=\"\$LIB$uppername\" test -z "$value" || LIBINTL="${LIBINTL}${LIBINTL:+ }$value" eval value=\"\$LTLIB$uppername\" test -z "$value" || LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }$value" else : fi else found_dir= found_la= found_so= found_a= eval libname=\"$acl_libname_spec\" # typically: libname=lib$name if test -n "$acl_shlibext"; then shrext=".$acl_shlibext" # typically: shrext=.so else shrext= fi if test $use_additional = yes; then dir="$additional_libdir" if test -n "$acl_shlibext"; then if test -f "$dir/$libname$shrext"; then found_dir="$dir" found_so="$dir/$libname$shrext" else if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then ver=`(cd "$dir" && \ for f in "$libname$shrext".*; do echo "$f"; done \ | sed -e "s,^$libname$shrext\\\\.,," \ | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ | sed 1q ) 2>/dev/null` if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then found_dir="$dir" found_so="$dir/$libname$shrext.$ver" fi else eval library_names=\"$acl_library_names_spec\" for f in $library_names; do if test -f "$dir/$f"; then found_dir="$dir" found_so="$dir/$f" break fi done fi fi fi if test "X$found_dir" = "X"; then if test -f "$dir/$libname.$acl_libext"; then found_dir="$dir" found_a="$dir/$libname.$acl_libext" fi fi if test "X$found_dir" != "X"; then if test -f "$dir/$libname.la"; then found_la="$dir/$libname.la" fi fi fi if test "X$found_dir" = "X"; then for x in $LDFLAGS $LTLIBINTL; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" case "$x" in -L*) dir=`echo "X$x" | sed -e 's/^X-L//'` if test -n "$acl_shlibext"; then if test -f "$dir/$libname$shrext"; then found_dir="$dir" found_so="$dir/$libname$shrext" else if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then ver=`(cd "$dir" && \ for f in "$libname$shrext".*; do echo "$f"; done \ | sed -e "s,^$libname$shrext\\\\.,," \ | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ | sed 1q ) 2>/dev/null` if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then found_dir="$dir" found_so="$dir/$libname$shrext.$ver" fi else eval library_names=\"$acl_library_names_spec\" for f in $library_names; do if test -f "$dir/$f"; then found_dir="$dir" found_so="$dir/$f" break fi done fi fi fi if test "X$found_dir" = "X"; then if test -f "$dir/$libname.$acl_libext"; then found_dir="$dir" found_a="$dir/$libname.$acl_libext" fi fi if test "X$found_dir" != "X"; then if test -f "$dir/$libname.la"; then found_la="$dir/$libname.la" fi fi ;; esac if test "X$found_dir" != "X"; then break fi done fi if test "X$found_dir" != "X"; then LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }-L$found_dir -l$name" if test "X$found_so" != "X"; then if test "$enable_rpath" = no \ || test "X$found_dir" = "X/usr/$acl_libdirstem" \ || test "X$found_dir" = "X/usr/$acl_libdirstem2"; then LIBINTL="${LIBINTL}${LIBINTL:+ }$found_so" else haveit= for x in $ltrpathdirs; do if test "X$x" = "X$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then ltrpathdirs="$ltrpathdirs $found_dir" fi if test "$acl_hardcode_direct" = yes; then LIBINTL="${LIBINTL}${LIBINTL:+ }$found_so" else if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then LIBINTL="${LIBINTL}${LIBINTL:+ }$found_so" haveit= for x in $rpathdirs; do if test "X$x" = "X$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then rpathdirs="$rpathdirs $found_dir" fi else haveit= for x in $LDFLAGS $LIBINTL; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X-L$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then LIBINTL="${LIBINTL}${LIBINTL:+ }-L$found_dir" fi if test "$acl_hardcode_minus_L" != no; then LIBINTL="${LIBINTL}${LIBINTL:+ }$found_so" else LIBINTL="${LIBINTL}${LIBINTL:+ }-l$name" fi fi fi fi else if test "X$found_a" != "X"; then LIBINTL="${LIBINTL}${LIBINTL:+ }$found_a" else LIBINTL="${LIBINTL}${LIBINTL:+ }-L$found_dir -l$name" fi fi additional_includedir= case "$found_dir" in */$acl_libdirstem | */$acl_libdirstem/) basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem/"'*$,,'` if test "$name" = 'intl'; then LIBINTL_PREFIX="$basedir" fi additional_includedir="$basedir/include" ;; */$acl_libdirstem2 | */$acl_libdirstem2/) basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem2/"'*$,,'` if test "$name" = 'intl'; then LIBINTL_PREFIX="$basedir" fi additional_includedir="$basedir/include" ;; esac if test "X$additional_includedir" != "X"; then if test "X$additional_includedir" != "X/usr/include"; then haveit= if test "X$additional_includedir" = "X/usr/local/include"; then if test -n "$GCC"; then case $host_os in linux* | gnu* | k*bsd*-gnu) haveit=yes;; esac fi fi if test -z "$haveit"; then for x in $CPPFLAGS $INCINTL; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X-I$additional_includedir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_includedir"; then INCINTL="${INCINTL}${INCINTL:+ }-I$additional_includedir" fi fi fi fi fi if test -n "$found_la"; then save_libdir="$libdir" case "$found_la" in */* | *\\*) . "$found_la" ;; *) . "./$found_la" ;; esac libdir="$save_libdir" for dep in $dependency_libs; do case "$dep" in -L*) additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` if test "X$additional_libdir" != "X/usr/$acl_libdirstem" \ && test "X$additional_libdir" != "X/usr/$acl_libdirstem2"; then haveit= if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem" \ || test "X$additional_libdir" = "X/usr/local/$acl_libdirstem2"; then if test -n "$GCC"; then case $host_os in linux* | gnu* | k*bsd*-gnu) haveit=yes;; esac fi fi if test -z "$haveit"; then haveit= for x in $LDFLAGS $LIBINTL; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X-L$additional_libdir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_libdir"; then LIBINTL="${LIBINTL}${LIBINTL:+ }-L$additional_libdir" fi fi haveit= for x in $LDFLAGS $LTLIBINTL; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X-L$additional_libdir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_libdir"; then LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }-L$additional_libdir" fi fi fi fi ;; -R*) dir=`echo "X$dep" | sed -e 's/^X-R//'` if test "$enable_rpath" != no; then haveit= for x in $rpathdirs; do if test "X$x" = "X$dir"; then haveit=yes break fi done if test -z "$haveit"; then rpathdirs="$rpathdirs $dir" fi haveit= for x in $ltrpathdirs; do if test "X$x" = "X$dir"; then haveit=yes break fi done if test -z "$haveit"; then ltrpathdirs="$ltrpathdirs $dir" fi fi ;; -l*) names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` ;; *.la) names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` ;; *) LIBINTL="${LIBINTL}${LIBINTL:+ }$dep" LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }$dep" ;; esac done fi else LIBINTL="${LIBINTL}${LIBINTL:+ }-l$name" LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }-l$name" fi fi fi done done if test "X$rpathdirs" != "X"; then if test -n "$acl_hardcode_libdir_separator"; then alldirs= for found_dir in $rpathdirs; do alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$found_dir" done acl_save_libdir="$libdir" libdir="$alldirs" eval flag=\"$acl_hardcode_libdir_flag_spec\" libdir="$acl_save_libdir" LIBINTL="${LIBINTL}${LIBINTL:+ }$flag" else for found_dir in $rpathdirs; do acl_save_libdir="$libdir" libdir="$found_dir" eval flag=\"$acl_hardcode_libdir_flag_spec\" libdir="$acl_save_libdir" LIBINTL="${LIBINTL}${LIBINTL:+ }$flag" done fi fi if test "X$ltrpathdirs" != "X"; then for found_dir in $ltrpathdirs; do LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }-R$found_dir" done fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GNU gettext in libintl" >&5 printf %s "checking for GNU gettext in libintl... " >&6; } if eval test \${$gt_func_gnugettext_libintl+y} then : printf %s "(cached) " >&6 else $as_nop gt_save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $INCINTL" gt_save_LIBS="$LIBS" LIBS="$LIBS $LIBINTL" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #ifndef __GNU_GETTEXT_SUPPORTED_REVISION extern int _nl_msg_cat_cntr; extern #ifdef __cplusplus "C" #endif const char *_nl_expand_alias (const char *); #define __GNU_GETTEXT_SYMBOL_EXPRESSION (_nl_msg_cat_cntr + *_nl_expand_alias ("")) #else #define __GNU_GETTEXT_SYMBOL_EXPRESSION 0 #endif $gt_revision_test_code int main (void) { bindtextdomain ("", ""); return * gettext ("")$gt_expression_test_code + __GNU_GETTEXT_SYMBOL_EXPRESSION ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : eval "$gt_func_gnugettext_libintl=yes" else $as_nop eval "$gt_func_gnugettext_libintl=no" fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" != yes; } && test -n "$LIBICONV"; then LIBS="$LIBS $LIBICONV" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #ifndef __GNU_GETTEXT_SUPPORTED_REVISION extern int _nl_msg_cat_cntr; extern #ifdef __cplusplus "C" #endif const char *_nl_expand_alias (const char *); #define __GNU_GETTEXT_SYMBOL_EXPRESSION (_nl_msg_cat_cntr + *_nl_expand_alias ("")) #else #define __GNU_GETTEXT_SYMBOL_EXPRESSION 0 #endif $gt_revision_test_code int main (void) { bindtextdomain ("", ""); return * gettext ("")$gt_expression_test_code + __GNU_GETTEXT_SYMBOL_EXPRESSION ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : LIBINTL="$LIBINTL $LIBICONV" LTLIBINTL="$LTLIBINTL $LTLIBICONV" eval "$gt_func_gnugettext_libintl=yes" fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext fi CPPFLAGS="$gt_save_CPPFLAGS" LIBS="$gt_save_LIBS" fi eval ac_res=\$$gt_func_gnugettext_libintl { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 printf "%s\n" "$ac_res" >&6; } fi if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" = "yes"; } \ || { { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; } \ && test "$PACKAGE" != gettext-runtime \ && test "$PACKAGE" != gettext-tools; }; then gt_use_preinstalled_gnugettext=yes else LIBINTL= LTLIBINTL= INCINTL= fi if test -n "$INTL_MACOSX_LIBS"; then if test "$gt_use_preinstalled_gnugettext" = "yes" \ || test "$nls_cv_use_gnu_gettext" = "yes"; then LIBINTL="$LIBINTL $INTL_MACOSX_LIBS" LTLIBINTL="$LTLIBINTL $INTL_MACOSX_LIBS" fi fi if test "$gt_use_preinstalled_gnugettext" = "yes" \ || test "$nls_cv_use_gnu_gettext" = "yes"; then printf "%s\n" "#define ENABLE_NLS 1" >>confdefs.h else USE_NLS=no fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to use NLS" >&5 printf %s "checking whether to use NLS... " >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $USE_NLS" >&5 printf "%s\n" "$USE_NLS" >&6; } if test "$USE_NLS" = "yes"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking where the gettext function comes from" >&5 printf %s "checking where the gettext function comes from... " >&6; } if test "$gt_use_preinstalled_gnugettext" = "yes"; then if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; }; then gt_source="external libintl" else gt_source="libc" fi else gt_source="included intl directory" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $gt_source" >&5 printf "%s\n" "$gt_source" >&6; } fi if test "$USE_NLS" = "yes"; then if test "$gt_use_preinstalled_gnugettext" = "yes"; then if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; }; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to link with libintl" >&5 printf %s "checking how to link with libintl... " >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $LIBINTL" >&5 printf "%s\n" "$LIBINTL" >&6; } for element in $INCINTL; do haveit= for x in $CPPFLAGS; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X$element"; then haveit=yes break fi done if test -z "$haveit"; then CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }$element" fi done fi printf "%s\n" "#define HAVE_GETTEXT 1" >>confdefs.h printf "%s\n" "#define HAVE_DCGETTEXT 1" >>confdefs.h fi POSUB=po fi INTLLIBS="$LIBINTL" # Check whether --enable-silent-rules was given. if test ${enable_silent_rules+y} then : enableval=$enable_silent_rules; fi case $enable_silent_rules in # ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=0;; esac am_make=${MAKE-make} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 printf %s "checking whether $am_make supports nested variables... " >&6; } if test ${am_cv_make_support_nested_variables+y} then : printf %s "(cached) " >&6 else $as_nop if printf "%s\n" 'TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 printf "%s\n" "$am_cv_make_support_nested_variables" >&6; } if test $am_cv_make_support_nested_variables = yes; then AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AM_BACKSLASH='\' if test "x$prefix" = xNONE; then prefix=$ac_default_prefix fi if test "x$exec_prefix" = xNONE; then exec_prefix=$prefix fi if test -z "${docdir}"; then docdir='${datadir}/doc/${PACKAGE}' fi _GEANY_STATUS="$_GEANY_STATUS Install Geany in:${prefix}" if test -n "${build}" -a -n "${target}"; then _GEANY_STATUS="$_GEANY_STATUS Building Geany on:${build}" _GEANY_STATUS="$_GEANY_STATUS Building Geany for:${target}" fi if test -n "$ac_tool_prefix"; then for ac_prog in ar lib "link -lib" do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_AR+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$AR"; then ac_cv_prog_AR="$AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_AR="$ac_tool_prefix$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AR=$ac_cv_prog_AR if test -n "$AR"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 printf "%s\n" "$AR" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$AR" && break done fi if test -z "$AR"; then ac_ct_AR=$AR for ac_prog in ar lib "link -lib" do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_AR+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_AR"; then ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_AR="$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_AR=$ac_cv_prog_ac_ct_AR if test -n "$ac_ct_AR"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 printf "%s\n" "$ac_ct_AR" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$ac_ct_AR" && break done if test "x$ac_ct_AR" = x; then AR="false" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac AR=$ac_ct_AR fi fi : ${AR=ar} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking the archiver ($AR) interface" >&5 printf %s "checking the archiver ($AR) interface... " >&6; } if test ${am_cv_ar_interface+y} then : printf %s "(cached) " >&6 else $as_nop ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu am_cv_ar_interface=ar cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int some_variable = 0; _ACEOF if ac_fn_c_try_compile "$LINENO" then : am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&5' { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5 (eval $am_ar_try) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test "$ac_status" -eq 0; then am_cv_ar_interface=ar else am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&5' { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5 (eval $am_ar_try) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test "$ac_status" -eq 0; then am_cv_ar_interface=lib else am_cv_ar_interface=unknown fi fi rm -f conftest.lib libconftest.a fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_ar_interface" >&5 printf "%s\n" "$am_cv_ar_interface" >&6; } case $am_cv_ar_interface in ar) ;; lib) # Microsoft lib, so override with the ar-lib wrapper script. # FIXME: It is wrong to rewrite AR. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__AR in this case, # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something # similar. AR="$am_aux_dir/ar-lib $AR" ;; unknown) as_fn_error $? "could not determine $AR interface" "$LINENO" 5 ;; esac case `pwd` in *\ * | *\ *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 printf "%s\n" "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; esac macro_version='2.4.7' macro_revision='2.4.7' ltmain=$ac_aux_dir/ltmain.sh # Backslashify metacharacters that are still active within # double-quoted strings. sed_quote_subst='s/\(["`$\\]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\(["`\\]\)/\\\1/g' # Sed substitution to delay expansion of an escaped shell variable in a # double_quote_subst'ed string. delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' # Sed substitution to delay expansion of an escaped single quote. delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' # Sed substitution to avoid accidental globbing in evaled expressions no_glob_subst='s/\*/\\\*/g' ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 printf %s "checking how to print strings... " >&6; } # Test print first, because it will be a builtin if present. if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='print -r --' elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='printf %s\n' else # Use this function as a fallback that always works. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $1 _LTECHO_EOF' } ECHO='func_fallback_echo' fi # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "" } case $ECHO in printf*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: printf" >&5 printf "%s\n" "printf" >&6; } ;; print*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 printf "%s\n" "print -r" >&6; } ;; *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: cat" >&5 printf "%s\n" "cat" >&6; } ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 printf %s "checking for a sed that does not truncate output... " >&6; } if test ${ac_cv_path_SED+y} then : printf %s "(cached) " >&6 else $as_nop ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ for ac_i in 1 2 3 4 5 6 7; do ac_script="$ac_script$as_nl$ac_script" done echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed { ac_script=; unset ac_script;} if test -z "$SED"; then ac_path_SED_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_prog in sed gsed do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_SED="$as_dir$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_SED" || continue # Check for GNU ac_path_SED and select it if it is found. # Check for GNU $ac_path_SED case `"$ac_path_SED" --version 2>&1` in *GNU*) ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; *) ac_count=0 printf %s 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" printf "%s\n" '' >> "conftest.nl" "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_SED_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_SED="$ac_path_SED" ac_path_SED_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_SED_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_SED"; then as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 fi else ac_cv_path_SED=$SED fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 printf "%s\n" "$ac_cv_path_SED" >&6; } SED="$ac_cv_path_SED" rm -f conftest.sed test -z "$SED" && SED=sed Xsed="$SED -e 1s/^X//" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 printf %s "checking for fgrep... " >&6; } if test ${ac_cv_path_FGREP+y} then : printf %s "(cached) " >&6 else $as_nop if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 then ac_cv_path_FGREP="$GREP -F" else if test -z "$FGREP"; then ac_path_FGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_prog in fgrep do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_FGREP="$as_dir$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_FGREP" || continue # Check for GNU ac_path_FGREP and select it if it is found. # Check for GNU $ac_path_FGREP case `"$ac_path_FGREP" --version 2>&1` in *GNU*) ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; *) ac_count=0 printf %s 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" printf "%s\n" 'FGREP' >> "conftest.nl" "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_FGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_FGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_FGREP"; then as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_FGREP=$FGREP fi fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 printf "%s\n" "$ac_cv_path_FGREP" >&6; } FGREP="$ac_cv_path_FGREP" test -z "$GREP" && GREP=grep # Check whether --with-gnu-ld was given. if test ${with_gnu_ld+y} then : withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes else $as_nop with_gnu_ld=no fi ac_prog=ld if test yes = "$GCC"; then # Check if gcc -print-prog-name=ld gives a path. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 printf %s "checking for ld used by $CC... " >&6; } case $host in *-*-mingw*) # gcc leaves a trailing carriage return, which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [\\/]* | ?:[\\/]*) re_direlt='/[^/][^/]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD=$ac_prog ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test yes = "$with_gnu_ld"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 printf %s "checking for GNU ld... " >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 printf %s "checking for non-GNU ld... " >&6; } fi if test ${lt_cv_path_LD+y} then : printf %s "(cached) " >&6 else $as_nop if test -z "$LD"; then lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD=$ac_dir/$ac_prog # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &5 printf "%s\n" "$LD" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 printf %s "checking if the linker ($LD) is GNU ld... " >&6; } if test ${lt_cv_prog_gnu_ld+y} then : printf %s "(cached) " >&6 else $as_nop # I'd rather use --version here, but apparently some GNU lds only accept -v. case `$LD -v 2>&1 &5 printf "%s\n" "$lt_cv_prog_gnu_ld" >&6; } with_gnu_ld=$lt_cv_prog_gnu_ld { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 printf %s "checking for BSD- or MS-compatible name lister (nm)... " >&6; } if test ${lt_cv_path_NM+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$NM"; then # Let the user override the test. lt_cv_path_NM=$NM else lt_nm_to_check=${ac_tool_prefix}nm if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. tmp_nm=$ac_dir/$lt_tmp_nm if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then # Check to see if the nm accepts a BSD-compat flag. # Adding the 'sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty case $build_os in mingw*) lt_bad_file=conftest.nm/nofile ;; *) lt_bad_file=/dev/null ;; esac case `"$tmp_nm" -B $lt_bad_file 2>&1 | $SED '1q'` in *$lt_bad_file* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break 2 ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | $SED '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break 2 ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but continue # so that we can try to find one that supports BSD flags ;; esac ;; esac fi done IFS=$lt_save_ifs done : ${lt_cv_path_NM=no} fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 printf "%s\n" "$lt_cv_path_NM" >&6; } if test no != "$lt_cv_path_NM"; then NM=$lt_cv_path_NM else # Didn't find any BSD compatible name lister, look for dumpbin. if test -n "$DUMPBIN"; then : # Let the user override the test. else if test -n "$ac_tool_prefix"; then for ac_prog in dumpbin "link -dump" do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_DUMPBIN+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$DUMPBIN"; then ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DUMPBIN=$ac_cv_prog_DUMPBIN if test -n "$DUMPBIN"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 printf "%s\n" "$DUMPBIN" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$DUMPBIN" && break done fi if test -z "$DUMPBIN"; then ac_ct_DUMPBIN=$DUMPBIN for ac_prog in dumpbin "link -dump" do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_DUMPBIN+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_DUMPBIN"; then ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN if test -n "$ac_ct_DUMPBIN"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 printf "%s\n" "$ac_ct_DUMPBIN" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$ac_ct_DUMPBIN" && break done if test "x$ac_ct_DUMPBIN" = x; then DUMPBIN=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DUMPBIN=$ac_ct_DUMPBIN fi fi case `$DUMPBIN -symbols -headers /dev/null 2>&1 | $SED '1q'` in *COFF*) DUMPBIN="$DUMPBIN -symbols -headers" ;; *) DUMPBIN=: ;; esac fi if test : != "$DUMPBIN"; then NM=$DUMPBIN fi fi test -z "$NM" && NM=nm { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 printf %s "checking the name lister ($NM) interface... " >&6; } if test ${lt_cv_nm_interface+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&5 (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&5 (eval echo "\"\$as_me:$LINENO: output\"" >&5) cat conftest.out >&5 if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" fi rm -f conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 printf "%s\n" "$lt_cv_nm_interface" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 printf %s "checking whether ln -s works... " >&6; } LN_S=$as_ln_s if test "$LN_S" = "ln -s"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 printf "%s\n" "no, using $LN_S" >&6; } fi # find the maximum length of command line arguments { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 printf %s "checking the maximum length of command line arguments... " >&6; } if test ${lt_cv_sys_max_cmd_len+y} then : printf %s "(cached) " >&6 else $as_nop i=0 teststring=ABCD case $build_os in msdosdjgpp*) # On DJGPP, this test can blow up pretty badly due to problems in libc # (any single argument exceeding 2000 bytes causes a buffer overrun # during glob expansion). Even if it were fixed, the result of this # check would be larger than it should be. lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; gnu*) # Under GNU Hurd, this test is not required because there is # no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; cygwin* | mingw* | cegcc*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, # you end up with a "frozen" computer, even though with patience # the test eventually succeeds (with a max line length of 256k). # Instead, let's just punt: use the minimum linelength reported by # all of the supported platforms: 8192 (on NT/2K/XP). lt_cv_sys_max_cmd_len=8192; ;; mint*) # On MiNT this can take a long time and run out of memory. lt_cv_sys_max_cmd_len=8192; ;; amigaos*) # On AmigaOS with pdksh, this test takes hours, literally. # So we just punt and use a minimum line length of 8192. lt_cv_sys_max_cmd_len=8192; ;; bitrig* | darwin* | dragonfly* | freebsd* | midnightbsd* | netbsd* | openbsd*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` elif test -x /usr/sbin/sysctl; then lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` else lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs fi # And add a safety zone lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ;; interix*) # We know the value 262144 and hardcode it with a safety zone (like BSD) lt_cv_sys_max_cmd_len=196608 ;; os2*) # The test takes a long time on OS/2. lt_cv_sys_max_cmd_len=8192 ;; osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not # nice to cause kernel panics so lets avoid the loop below. # First set a reasonable default. lt_cv_sys_max_cmd_len=16384 # if test -x /sbin/sysconfig; then case `/sbin/sysconfig -q proc exec_disable_arg_limit` in *1*) lt_cv_sys_max_cmd_len=-1 ;; esac fi ;; sco3.2v5*) lt_cv_sys_max_cmd_len=102400 ;; sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then lt_cv_sys_max_cmd_len=`echo $kargmax | $SED 's/.*[ ]//'` else lt_cv_sys_max_cmd_len=32768 fi ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` if test -n "$lt_cv_sys_max_cmd_len" && \ test undefined != "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. for i in 1 2 3 4 5 6 7 8; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. while { test X`env echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && test 17 != "$i" # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring done # Only check the string length outside the loop. lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` teststring= # Add a significant safety factor because C++ compilers can tack on # massive amounts of additional arguments before passing them to the # linker. It appears as though 1/2 is a usable value. lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` fi ;; esac fi if test -n "$lt_cv_sys_max_cmd_len"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 printf "%s\n" "$lt_cv_sys_max_cmd_len" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none" >&5 printf "%s\n" "none" >&6; } fi max_cmd_len=$lt_cv_sys_max_cmd_len : ${CP="cp -f"} : ${MV="mv -f"} : ${RM="rm -f"} if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else lt_unset=false fi # test EBCDIC or ASCII case `echo X|tr X '\101'` in A) # ASCII based system # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr lt_SP2NL='tr \040 \012' lt_NL2SP='tr \015\012 \040\040' ;; *) # EBCDIC based system lt_SP2NL='tr \100 \n' lt_NL2SP='tr \r\n \100\100' ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5 printf %s "checking how to convert $build file names to $host format... " >&6; } if test ${lt_cv_to_host_file_cmd+y} then : printf %s "(cached) " >&6 else $as_nop case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 ;; esac ;; *-*-cygwin* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_noop ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin ;; esac ;; * ) # unhandled hosts (and "normal" native builds) lt_cv_to_host_file_cmd=func_convert_file_noop ;; esac fi to_host_file_cmd=$lt_cv_to_host_file_cmd { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5 printf "%s\n" "$lt_cv_to_host_file_cmd" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5 printf %s "checking how to convert $build file names to toolchain format... " >&6; } if test ${lt_cv_to_tool_file_cmd+y} then : printf %s "(cached) " >&6 else $as_nop #assume ordinary cross tools, or native build. lt_cv_to_tool_file_cmd=func_convert_file_noop case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 ;; esac ;; esac fi to_tool_file_cmd=$lt_cv_to_tool_file_cmd { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5 printf "%s\n" "$lt_cv_to_tool_file_cmd" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 printf %s "checking for $LD option to reload object files... " >&6; } if test ${lt_cv_ld_reload_flag+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_ld_reload_flag='-r' fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 printf "%s\n" "$lt_cv_ld_reload_flag" >&6; } reload_flag=$lt_cv_ld_reload_flag case $reload_flag in "" | " "*) ;; *) reload_flag=" $reload_flag" ;; esac reload_cmds='$LD$reload_flag -o $output$reload_objs' case $host_os in cygwin* | mingw* | pw32* | cegcc*) if test yes != "$GCC"; then reload_cmds=false fi ;; darwin*) if test yes = "$GCC"; then reload_cmds='$LTCC $LTCFLAGS -nostdlib $wl-r -o $output$reload_objs' else reload_cmds='$LD$reload_flag -o $output$reload_objs' fi ;; esac if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}file", so it can be a program name with args. set dummy ${ac_tool_prefix}file; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_FILECMD+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$FILECMD"; then ac_cv_prog_FILECMD="$FILECMD" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_FILECMD="${ac_tool_prefix}file" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi FILECMD=$ac_cv_prog_FILECMD if test -n "$FILECMD"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $FILECMD" >&5 printf "%s\n" "$FILECMD" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_FILECMD"; then ac_ct_FILECMD=$FILECMD # Extract the first word of "file", so it can be a program name with args. set dummy file; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_FILECMD+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_FILECMD"; then ac_cv_prog_ac_ct_FILECMD="$ac_ct_FILECMD" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_FILECMD="file" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_FILECMD=$ac_cv_prog_ac_ct_FILECMD if test -n "$ac_ct_FILECMD"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_FILECMD" >&5 printf "%s\n" "$ac_ct_FILECMD" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_FILECMD" = x; then FILECMD=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac FILECMD=$ac_ct_FILECMD fi else FILECMD="$ac_cv_prog_FILECMD" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. set dummy ${ac_tool_prefix}objdump; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_OBJDUMP+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$OBJDUMP"; then ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OBJDUMP=$ac_cv_prog_OBJDUMP if test -n "$OBJDUMP"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 printf "%s\n" "$OBJDUMP" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_OBJDUMP"; then ac_ct_OBJDUMP=$OBJDUMP # Extract the first word of "objdump", so it can be a program name with args. set dummy objdump; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_OBJDUMP+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_OBJDUMP"; then ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OBJDUMP="objdump" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP if test -n "$ac_ct_OBJDUMP"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 printf "%s\n" "$ac_ct_OBJDUMP" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_OBJDUMP" = x; then OBJDUMP="false" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OBJDUMP=$ac_ct_OBJDUMP fi else OBJDUMP="$ac_cv_prog_OBJDUMP" fi test -z "$OBJDUMP" && OBJDUMP=objdump { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 printf %s "checking how to recognize dependent libraries... " >&6; } if test ${lt_cv_deplibs_check_method+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_file_magic_cmd='$MAGIC_CMD' lt_cv_file_magic_test_file= lt_cv_deplibs_check_method='unknown' # Need to set the preceding variable on all platforms that support # interlibrary dependencies. # 'none' -- dependencies not supported. # 'unknown' -- same as none, but documents that we really don't know. # 'pass_all' -- all dependencies passed with no checks. # 'test_compile' -- check by making test program. # 'file_magic [[regex]]' -- check by looking for files in library path # that responds to the $file_magic_cmd with a given extended regex. # If you have 'file' or equivalent on your system and you're not sure # whether 'pass_all' will *always* work, you probably want this one. case $host_os in aix[4-9]*) lt_cv_deplibs_check_method=pass_all ;; beos*) lt_cv_deplibs_check_method=pass_all ;; bsdi[45]*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' lt_cv_file_magic_cmd='$FILECMD -L' lt_cv_file_magic_test_file=/shlib/libc.so ;; cygwin*) # func_win32_libid is a shell function defined in ltmain.sh lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' ;; mingw* | pw32*) # Base MSYS/MinGW do not provide the 'file' command needed by # func_win32_libid shell function, so use a weaker test based on 'objdump', # unless we find 'file', for example because we are cross-compiling. if ( file / ) >/dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else # Keep this pattern in sync with the one in func_win32_libid. lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' lt_cv_file_magic_cmd='$OBJDUMP -f' fi ;; cegcc*) # use the weaker test based on 'objdump'. See mingw*. lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' lt_cv_file_magic_cmd='$OBJDUMP -f' ;; darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; freebsd* | dragonfly* | midnightbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' lt_cv_file_magic_cmd=$FILECMD lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac else lt_cv_deplibs_check_method=pass_all fi ;; haiku*) lt_cv_deplibs_check_method=pass_all ;; hpux10.20* | hpux11*) lt_cv_file_magic_cmd=$FILECMD case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ;; hppa*64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ;; *) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' lt_cv_file_magic_test_file=/usr/lib/libc.sl ;; esac ;; interix[3-9]*) # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' ;; irix5* | irix6* | nonstopux*) case $LD in *-32|*"-32 ") libmagic=32-bit;; *-n32|*"-n32 ") libmagic=N32;; *-64|*"-64 ") libmagic=64-bit;; *) libmagic=never-match;; esac lt_cv_deplibs_check_method=pass_all ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) lt_cv_deplibs_check_method=pass_all ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' fi ;; newos6*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' lt_cv_file_magic_cmd=$FILECMD lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; *nto* | *qnx*) lt_cv_deplibs_check_method=pass_all ;; openbsd* | bitrig*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' fi ;; osf3* | osf4* | osf5*) lt_cv_deplibs_check_method=pass_all ;; rdos*) lt_cv_deplibs_check_method=pass_all ;; solaris*) lt_cv_deplibs_check_method=pass_all ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; sysv4 | sysv4.3*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ;; ncr) lt_cv_deplibs_check_method=pass_all ;; sequent) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' ;; sni) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" lt_cv_file_magic_test_file=/lib/libc.so ;; siemens) lt_cv_deplibs_check_method=pass_all ;; pc) lt_cv_deplibs_check_method=pass_all ;; esac ;; tpf*) lt_cv_deplibs_check_method=pass_all ;; os2*) lt_cv_deplibs_check_method=pass_all ;; esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 printf "%s\n" "$lt_cv_deplibs_check_method" >&6; } file_magic_glob= want_nocaseglob=no if test "$build" = "$host"; then case $host_os in mingw* | pw32*) if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then want_nocaseglob=yes else file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"` fi ;; esac fi file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method test -z "$deplibs_check_method" && deplibs_check_method=unknown if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. set dummy ${ac_tool_prefix}dlltool; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_DLLTOOL+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$DLLTOOL"; then ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DLLTOOL=$ac_cv_prog_DLLTOOL if test -n "$DLLTOOL"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 printf "%s\n" "$DLLTOOL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_DLLTOOL"; then ac_ct_DLLTOOL=$DLLTOOL # Extract the first word of "dlltool", so it can be a program name with args. set dummy dlltool; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_DLLTOOL+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_DLLTOOL"; then ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DLLTOOL="dlltool" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL if test -n "$ac_ct_DLLTOOL"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 printf "%s\n" "$ac_ct_DLLTOOL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_DLLTOOL" = x; then DLLTOOL="false" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DLLTOOL=$ac_ct_DLLTOOL fi else DLLTOOL="$ac_cv_prog_DLLTOOL" fi test -z "$DLLTOOL" && DLLTOOL=dlltool { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5 printf %s "checking how to associate runtime and link libraries... " >&6; } if test ${lt_cv_sharedlib_from_linklib_cmd+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_sharedlib_from_linklib_cmd='unknown' case $host_os in cygwin* | mingw* | pw32* | cegcc*) # two different shell functions defined in ltmain.sh; # decide which one to use based on capabilities of $DLLTOOL case `$DLLTOOL --help 2>&1` in *--identify-strict*) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib ;; *) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback ;; esac ;; *) # fallback: assume linklib IS sharedlib lt_cv_sharedlib_from_linklib_cmd=$ECHO ;; esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5 printf "%s\n" "$lt_cv_sharedlib_from_linklib_cmd" >&6; } sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO if test -n "$ac_tool_prefix"; then for ac_prog in ar do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_AR+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$AR"; then ac_cv_prog_AR="$AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_AR="$ac_tool_prefix$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AR=$ac_cv_prog_AR if test -n "$AR"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 printf "%s\n" "$AR" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$AR" && break done fi if test -z "$AR"; then ac_ct_AR=$AR for ac_prog in ar do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_AR+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_AR"; then ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_AR="$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_AR=$ac_cv_prog_ac_ct_AR if test -n "$ac_ct_AR"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 printf "%s\n" "$ac_ct_AR" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$ac_ct_AR" && break done if test "x$ac_ct_AR" = x; then AR="false" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac AR=$ac_ct_AR fi fi : ${AR=ar} # Use ARFLAGS variable as AR's operation code to sync the variable naming with # Automake. If both AR_FLAGS and ARFLAGS are specified, AR_FLAGS should have # higher priority because thats what people were doing historically (setting # ARFLAGS for automake and AR_FLAGS for libtool). FIXME: Make the AR_FLAGS # variable obsoleted/removed. test ${AR_FLAGS+y} || AR_FLAGS=${ARFLAGS-cr} lt_ar_flags=$AR_FLAGS # Make AR_FLAGS overridable by 'make ARFLAGS='. Don't try to run-time override # by AR_FLAGS because that was never working and AR_FLAGS is about to die. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5 printf %s "checking for archiver @FILE support... " >&6; } if test ${lt_cv_ar_at_file+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_ar_at_file=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : echo conftest.$ac_objext > conftest.lst lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5' { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 (eval $lt_ar_try) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test 0 -eq "$ac_status"; then # Ensure the archiver fails upon bogus file names. rm -f conftest.$ac_objext libconftest.a { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 (eval $lt_ar_try) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test 0 -ne "$ac_status"; then lt_cv_ar_at_file=@ fi fi rm -f conftest.* libconftest.a fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 printf "%s\n" "$lt_cv_ar_at_file" >&6; } if test no = "$lt_cv_ar_at_file"; then archiver_list_spec= else archiver_list_spec=$lt_cv_ar_at_file fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_STRIP+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 printf "%s\n" "$STRIP" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_STRIP+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 printf "%s\n" "$ac_ct_STRIP" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi test -z "$STRIP" && STRIP=: if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_RANLIB+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi RANLIB=$ac_cv_prog_RANLIB if test -n "$RANLIB"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 printf "%s\n" "$RANLIB" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_RANLIB"; then ac_ct_RANLIB=$RANLIB # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_RANLIB+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_RANLIB"; then ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_RANLIB="ranlib" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB if test -n "$ac_ct_RANLIB"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 printf "%s\n" "$ac_ct_RANLIB" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_RANLIB" = x; then RANLIB=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac RANLIB=$ac_ct_RANLIB fi else RANLIB="$ac_cv_prog_RANLIB" fi test -z "$RANLIB" && RANLIB=: # Determine commands to create old-style static archives. old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in bitrig* | openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" fi case $host_os in darwin*) lock_old_archive_extraction=yes ;; *) lock_old_archive_extraction=no ;; esac # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # Check for command to grab the raw symbol name followed by C symbol from nm. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 printf %s "checking command to parse $NM output from $compiler object... " >&6; } if test ${lt_cv_sys_global_symbol_pipe+y} then : printf %s "(cached) " >&6 else $as_nop # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. symcode='[BCDEGRST]' # Regexp to match symbols that can be accessed directly from C. sympat='\([_A-Za-z][_A-Za-z0-9]*\)' # Define system-specific variables. case $host_os in aix*) symcode='[BCDT]' ;; cygwin* | mingw* | pw32* | cegcc*) symcode='[ABCDGISTW]' ;; hpux*) if test ia64 = "$host_cpu"; then symcode='[ABCDEGRST]' fi ;; irix* | nonstopux*) symcode='[BCDEGRST]' ;; osf*) symcode='[BCDEGQRST]' ;; solaris*) symcode='[BDRT]' ;; sco3.2v5*) symcode='[DT]' ;; sysv4.2uw2*) symcode='[DT]' ;; sysv5* | sco5v6* | unixware* | OpenUNIX*) symcode='[ABDT]' ;; sysv4) symcode='[DFNSTU]' ;; esac # If we're using GNU nm, then use its standard symbol codes. case `$NM -V 2>&1` in *GNU* | *'with BFD'*) symcode='[ABCDGIRSTW]' ;; esac if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Gets list of data symbols to import. lt_cv_sys_global_symbol_to_import="$SED -n -e 's/^I .* \(.*\)$/\1/p'" # Adjust the below global symbol transforms to fixup imported variables. lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" lt_c_name_lib_hook="\ -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\ -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'" else # Disable hooks by default. lt_cv_sys_global_symbol_to_import= lt_cdecl_hook= lt_c_name_hook= lt_c_name_lib_hook= fi # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. lt_cv_sys_global_symbol_to_cdecl="$SED -n"\ $lt_cdecl_hook\ " -e 's/^T .* \(.*\)$/extern int \1();/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address lt_cv_sys_global_symbol_to_c_name_address="$SED -n"\ $lt_c_name_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" # Transform an extracted symbol line into symbol name with lib prefix and # symbol address. lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="$SED -n"\ $lt_c_name_lib_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'" # Handle CRLF in mingw tool chain opt_cr= case $build_os in mingw*) opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac # Try without a prefix underscore, then with it. for ac_symprfx in "" "_"; do # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. symxfrm="\\1 $ac_symprfx\\2 \\2" # Write the raw and C identifiers. if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function, # D for any global variable and I for any imported variable. # Also find C++ and __fastcall symbols from MSVC++ or ICC, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK '"\ " {last_section=section; section=\$ 3};"\ " /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\ " /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\ " /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\ " {split(\$ 0,a,/\||\r/); split(a[2],s)};"\ " s[1]~/^[@?]/{print f,s[1],s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx" else lt_cv_sys_global_symbol_pipe="$SED -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | $SED '/ __gnu_lto/d'" # Check to see that the pipe works correctly. pipe_works=no rm -f conftest* cat > conftest.$ac_ext <<_LT_EOF #ifdef __cplusplus extern "C" { #endif char nm_test_var; void nm_test_func(void); void nm_test_func(void){} #ifdef __cplusplus } #endif int main(){nm_test_var='a';nm_test_func();return(0);} _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then # Now try to grab the symbols. nlist=conftest.nm $ECHO "$as_me:$LINENO: $NM conftest.$ac_objext | $lt_cv_sys_global_symbol_pipe > $nlist" >&5 if eval "$NM" conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist 2>&5 && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" else rm -f "$nlist"T fi # Make sure that we snagged all the symbols we need. if $GREP ' nm_test_var$' "$nlist" >/dev/null; then if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE /* DATA imports from DLLs on WIN32 can't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT_DLSYM_CONST #elif defined __osf__ /* This system does not cope well with relocations in const data. */ # define LT_DLSYM_CONST #else # define LT_DLSYM_CONST const #endif #ifdef __cplusplus extern "C" { #endif _LT_EOF # Now generate the symbol file. eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' cat <<_LT_EOF >> conftest.$ac_ext /* The mapping between symbol names and symbols. */ LT_DLSYM_CONST struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt__PROGRAM__LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif _LT_EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext lt_globsym_save_LIBS=$LIBS lt_globsym_save_CFLAGS=$CFLAGS LIBS=conftstm.$ac_objext CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s conftest$ac_exeext; then pipe_works=yes fi LIBS=$lt_globsym_save_LIBS CFLAGS=$lt_globsym_save_CFLAGS else echo "cannot find nm_test_func in $nlist" >&5 fi else echo "cannot find nm_test_var in $nlist" >&5 fi else echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 fi else echo "$progname: failed program was:" >&5 cat conftest.$ac_ext >&5 fi rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test yes = "$pipe_works"; then break else lt_cv_sys_global_symbol_pipe= fi done fi if test -z "$lt_cv_sys_global_symbol_pipe"; then lt_cv_sys_global_symbol_to_cdecl= fi if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: failed" >&5 printf "%s\n" "failed" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ok" >&5 printf "%s\n" "ok" >&6; } fi # Response file support. if test "$lt_cv_nm_interface" = "MS dumpbin"; then nm_file_list_spec='@' elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then nm_file_list_spec='@' fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 printf %s "checking for sysroot... " >&6; } # Check whether --with-sysroot was given. if test ${with_sysroot+y} then : withval=$with_sysroot; else $as_nop with_sysroot=no fi lt_sysroot= case $with_sysroot in #( yes) if test yes = "$GCC"; then lt_sysroot=`$CC --print-sysroot 2>/dev/null` fi ;; #( /*) lt_sysroot=`echo "$with_sysroot" | $SED -e "$sed_quote_subst"` ;; #( no|'') ;; #( *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_sysroot" >&5 printf "%s\n" "$with_sysroot" >&6; } as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5 ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5 printf "%s\n" "${lt_sysroot:-no}" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a working dd" >&5 printf %s "checking for a working dd... " >&6; } if test ${ac_cv_path_lt_DD+y} then : printf %s "(cached) " >&6 else $as_nop printf 0123456789abcdef0123456789abcdef >conftest.i cat conftest.i conftest.i >conftest2.i : ${lt_DD:=$DD} if test -z "$lt_DD"; then ac_path_lt_DD_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_prog in dd do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_lt_DD="$as_dir$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_lt_DD" || continue if "$ac_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then cmp -s conftest.i conftest.out \ && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=: fi $ac_path_lt_DD_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_lt_DD"; then : fi else ac_cv_path_lt_DD=$lt_DD fi rm -f conftest.i conftest2.i conftest.out fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_lt_DD" >&5 printf "%s\n" "$ac_cv_path_lt_DD" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to truncate binary pipes" >&5 printf %s "checking how to truncate binary pipes... " >&6; } if test ${lt_cv_truncate_bin+y} then : printf %s "(cached) " >&6 else $as_nop printf 0123456789abcdef0123456789abcdef >conftest.i cat conftest.i conftest.i >conftest2.i lt_cv_truncate_bin= if "$ac_cv_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then cmp -s conftest.i conftest.out \ && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1" fi rm -f conftest.i conftest2.i conftest.out test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_truncate_bin" >&5 printf "%s\n" "$lt_cv_truncate_bin" >&6; } # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. func_cc_basename () { for cc_temp in $*""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` } # Check whether --enable-libtool-lock was given. if test ${enable_libtool_lock+y} then : enableval=$enable_libtool_lock; fi test no = "$enable_libtool_lock" || enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) # Find out what ABI is being produced by ac_compile, and set mode # options accordingly. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `$FILECMD conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE=32 ;; *ELF-64*) HPUX_IA64_MODE=64 ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo '#line '$LINENO' "configure"' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then if test yes = "$lt_cv_prog_gnu_ld"; then case `$FILECMD conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `$FILECMD conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; *N32*) LD="${LD-ld} -n32" ;; *64-bit*) LD="${LD-ld} -64" ;; esac fi fi rm -rf conftest* ;; mips64*-*linux*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo '#line '$LINENO' "configure"' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then emul=elf case `$FILECMD conftest.$ac_objext` in *32-bit*) emul="${emul}32" ;; *64-bit*) emul="${emul}64" ;; esac case `$FILECMD conftest.$ac_objext` in *MSB*) emul="${emul}btsmip" ;; *LSB*) emul="${emul}ltsmip" ;; esac case `$FILECMD conftest.$ac_objext` in *N32*) emul="${emul}n32" ;; esac LD="${LD-ld} -m $emul" fi rm -rf conftest* ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. Note that the listed cases only cover the # situations where additional linker options are needed (such as when # doing 32-bit compilation for a host where ld defaults to 64-bit, or # vice versa); the common cases where no linker options are needed do # not appear in the list. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `$FILECMD conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) case `$FILECMD conftest.o` in *x86-64*) LD="${LD-ld} -m elf32_x86_64" ;; *) LD="${LD-ld} -m elf_i386" ;; esac ;; powerpc64le-*linux*) LD="${LD-ld} -m elf32lppclinux" ;; powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) LD="${LD-ld} -m elf_s390" ;; sparc64-*linux*) LD="${LD-ld} -m elf32_sparc" ;; esac ;; *64-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; powerpcle-*linux*) LD="${LD-ld} -m elf64lppc" ;; powerpc-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) LD="${LD-ld} -m elf64_s390" ;; sparc*-*linux*) LD="${LD-ld} -m elf64_sparc" ;; esac ;; esac fi rm -rf conftest* ;; *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. SAVE_CFLAGS=$CFLAGS CFLAGS="$CFLAGS -belf" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 printf %s "checking whether the C compiler needs -belf... " >&6; } if test ${lt_cv_cc_needs_belf+y} then : printf %s "(cached) " >&6 else $as_nop ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : lt_cv_cc_needs_belf=yes else $as_nop lt_cv_cc_needs_belf=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 printf "%s\n" "$lt_cv_cc_needs_belf" >&6; } if test yes != "$lt_cv_cc_needs_belf"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS=$SAVE_CFLAGS fi ;; *-*solaris*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `$FILECMD conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) case $host in i?86-*-solaris*|x86_64-*-solaris*) LD="${LD-ld} -m elf_x86_64" ;; sparc*-*-solaris*) LD="${LD-ld} -m elf64_sparc" ;; esac # GNU ld 2.21 introduced _sol2 emulations. Use them if available. if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then LD=${LD-ld}_sol2 fi ;; *) if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then LD="${LD-ld} -64" fi ;; esac ;; esac fi rm -rf conftest* ;; esac need_locks=$enable_libtool_lock if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args. set dummy ${ac_tool_prefix}mt; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_MANIFEST_TOOL+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$MANIFEST_TOOL"; then ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL if test -n "$MANIFEST_TOOL"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5 printf "%s\n" "$MANIFEST_TOOL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_MANIFEST_TOOL"; then ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL # Extract the first word of "mt", so it can be a program name with args. set dummy mt; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_MANIFEST_TOOL+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_MANIFEST_TOOL"; then ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_MANIFEST_TOOL="mt" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL if test -n "$ac_ct_MANIFEST_TOOL"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5 printf "%s\n" "$ac_ct_MANIFEST_TOOL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_MANIFEST_TOOL" = x; then MANIFEST_TOOL=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL fi else MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL" fi test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5 printf %s "checking if $MANIFEST_TOOL is a manifest tool... " >&6; } if test ${lt_cv_path_mainfest_tool+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_path_mainfest_tool=no echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5 $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out cat conftest.err >&5 if $GREP 'Manifest Tool' conftest.out > /dev/null; then lt_cv_path_mainfest_tool=yes fi rm -f conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 printf "%s\n" "$lt_cv_path_mainfest_tool" >&6; } if test yes != "$lt_cv_path_mainfest_tool"; then MANIFEST_TOOL=: fi case $host_os in rhapsody* | darwin*) if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_DSYMUTIL+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$DSYMUTIL"; then ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DSYMUTIL=$ac_cv_prog_DSYMUTIL if test -n "$DSYMUTIL"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 printf "%s\n" "$DSYMUTIL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_DSYMUTIL"; then ac_ct_DSYMUTIL=$DSYMUTIL # Extract the first word of "dsymutil", so it can be a program name with args. set dummy dsymutil; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_DSYMUTIL+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_DSYMUTIL"; then ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL if test -n "$ac_ct_DSYMUTIL"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 printf "%s\n" "$ac_ct_DSYMUTIL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_DSYMUTIL" = x; then DSYMUTIL=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DSYMUTIL=$ac_ct_DSYMUTIL fi else DSYMUTIL="$ac_cv_prog_DSYMUTIL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. set dummy ${ac_tool_prefix}nmedit; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_NMEDIT+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$NMEDIT"; then ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi NMEDIT=$ac_cv_prog_NMEDIT if test -n "$NMEDIT"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 printf "%s\n" "$NMEDIT" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_NMEDIT"; then ac_ct_NMEDIT=$NMEDIT # Extract the first word of "nmedit", so it can be a program name with args. set dummy nmedit; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_NMEDIT+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_NMEDIT"; then ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_NMEDIT="nmedit" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT if test -n "$ac_ct_NMEDIT"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 printf "%s\n" "$ac_ct_NMEDIT" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_NMEDIT" = x; then NMEDIT=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac NMEDIT=$ac_ct_NMEDIT fi else NMEDIT="$ac_cv_prog_NMEDIT" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. set dummy ${ac_tool_prefix}lipo; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_LIPO+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$LIPO"; then ac_cv_prog_LIPO="$LIPO" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_LIPO="${ac_tool_prefix}lipo" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi LIPO=$ac_cv_prog_LIPO if test -n "$LIPO"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 printf "%s\n" "$LIPO" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_LIPO"; then ac_ct_LIPO=$LIPO # Extract the first word of "lipo", so it can be a program name with args. set dummy lipo; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_LIPO+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_LIPO"; then ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_LIPO="lipo" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO if test -n "$ac_ct_LIPO"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 printf "%s\n" "$ac_ct_LIPO" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_LIPO" = x; then LIPO=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac LIPO=$ac_ct_LIPO fi else LIPO="$ac_cv_prog_LIPO" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. set dummy ${ac_tool_prefix}otool; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_OTOOL+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$OTOOL"; then ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_OTOOL="${ac_tool_prefix}otool" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OTOOL=$ac_cv_prog_OTOOL if test -n "$OTOOL"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 printf "%s\n" "$OTOOL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_OTOOL"; then ac_ct_OTOOL=$OTOOL # Extract the first word of "otool", so it can be a program name with args. set dummy otool; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_OTOOL+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_OTOOL"; then ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OTOOL="otool" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL if test -n "$ac_ct_OTOOL"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 printf "%s\n" "$ac_ct_OTOOL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_OTOOL" = x; then OTOOL=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OTOOL=$ac_ct_OTOOL fi else OTOOL="$ac_cv_prog_OTOOL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. set dummy ${ac_tool_prefix}otool64; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_OTOOL64+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$OTOOL64"; then ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OTOOL64=$ac_cv_prog_OTOOL64 if test -n "$OTOOL64"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 printf "%s\n" "$OTOOL64" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_OTOOL64"; then ac_ct_OTOOL64=$OTOOL64 # Extract the first word of "otool64", so it can be a program name with args. set dummy otool64; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_OTOOL64+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_OTOOL64"; then ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OTOOL64="otool64" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 if test -n "$ac_ct_OTOOL64"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 printf "%s\n" "$ac_ct_OTOOL64" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_OTOOL64" = x; then OTOOL64=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OTOOL64=$ac_ct_OTOOL64 fi else OTOOL64="$ac_cv_prog_OTOOL64" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 printf %s "checking for -single_module linker flag... " >&6; } if test ${lt_cv_apple_cc_single_mod+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_apple_cc_single_mod=no if test -z "$LT_MULTI_MODULE"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the # link flags. rm -rf libconftest.dylib* echo "int foo(void){return 1;}" > conftest.c echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c" >&5 $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? # If there is a non-empty error log, and "single_module" # appears in it, assume the flag caused a linker warning if test -s conftest.err && $GREP single_module conftest.err; then cat conftest.err >&5 # Otherwise, if the output was created with a 0 exit code from # the compiler, it worked. elif test -f libconftest.dylib && test 0 = "$_lt_result"; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&5 fi rm -rf libconftest.dylib* rm -f conftest.* fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 printf "%s\n" "$lt_cv_apple_cc_single_mod" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 printf %s "checking for -exported_symbols_list linker flag... " >&6; } if test ${lt_cv_ld_exported_symbols_list+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_ld_exported_symbols_list=no save_LDFLAGS=$LDFLAGS echo "_main" > conftest.sym LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : lt_cv_ld_exported_symbols_list=yes else $as_nop lt_cv_ld_exported_symbols_list=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 printf "%s\n" "$lt_cv_ld_exported_symbols_list" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 printf %s "checking for -force_load linker flag... " >&6; } if test ${lt_cv_ld_force_load+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_ld_force_load=no cat > conftest.c << _LT_EOF int forced_loaded() { return 2;} _LT_EOF echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 echo "$AR $AR_FLAGS libconftest.a conftest.o" >&5 $AR $AR_FLAGS libconftest.a conftest.o 2>&5 echo "$RANLIB libconftest.a" >&5 $RANLIB libconftest.a 2>&5 cat > conftest.c << _LT_EOF int main() { return 0;} _LT_EOF echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err _lt_result=$? if test -s conftest.err && $GREP force_load conftest.err; then cat conftest.err >&5 elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then lt_cv_ld_force_load=yes else cat conftest.err >&5 fi rm -f conftest.err libconftest.a conftest conftest.c rm -rf conftest.dSYM fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 printf "%s\n" "$lt_cv_ld_force_load" >&6; } case $host_os in rhapsody* | darwin1.[012]) _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; darwin*) case $MACOSX_DEPLOYMENT_TARGET,$host in 10.[012],*|,*powerpc*-darwin[5-8]*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; *) _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; esac ;; esac if test yes = "$lt_cv_apple_cc_single_mod"; then _lt_dar_single_mod='$single_module' fi if test yes = "$lt_cv_ld_exported_symbols_list"; then _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' else _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib' fi if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac # func_munge_path_list VARIABLE PATH # ----------------------------------- # VARIABLE is name of variable containing _space_ separated list of # directories to be munged by the contents of PATH, which is string # having a format: # "DIR[:DIR]:" # string "DIR[ DIR]" will be prepended to VARIABLE # ":DIR[:DIR]" # string "DIR[ DIR]" will be appended to VARIABLE # "DIRP[:DIRP]::[DIRA:]DIRA" # string "DIRP[ DIRP]" will be prepended to VARIABLE and string # "DIRA[ DIRA]" will be appended to VARIABLE # "DIR[:DIR]" # VARIABLE will be replaced by "DIR[ DIR]" func_munge_path_list () { case x$2 in x) ;; *:) eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\" ;; x:*) eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\" ;; *::*) eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\" ;; *) eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\" ;; esac } ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default " if test "x$ac_cv_header_dlfcn_h" = xyes then : printf "%s\n" "#define HAVE_DLFCN_H 1" >>confdefs.h fi # Set options # Check whether --enable-static was given. if test ${enable_static+y} then : enableval=$enable_static; p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS=$lt_save_ifs ;; esac else $as_nop enable_static=no fi enable_dlopen=no enable_win32_dll=no # Check whether --enable-shared was given. if test ${enable_shared+y} then : enableval=$enable_shared; p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_shared=yes fi done IFS=$lt_save_ifs ;; esac else $as_nop enable_shared=yes fi # Check whether --with-pic was given. if test ${with_pic+y} then : withval=$with_pic; lt_p=${PACKAGE-default} case $withval in yes|no) pic_mode=$withval ;; *) pic_mode=default # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for lt_pkg in $withval; do IFS=$lt_save_ifs if test "X$lt_pkg" = "X$lt_p"; then pic_mode=yes fi done IFS=$lt_save_ifs ;; esac else $as_nop pic_mode=default fi # Check whether --enable-fast-install was given. if test ${enable_fast_install+y} then : enableval=$enable_fast_install; p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done IFS=$lt_save_ifs ;; esac else $as_nop enable_fast_install=yes fi shared_archive_member_spec= case $host,$enable_shared in power*-*-aix[5-9]*,yes) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking which variant of shared library versioning to provide" >&5 printf %s "checking which variant of shared library versioning to provide... " >&6; } # Check whether --with-aix-soname was given. if test ${with_aix_soname+y} then : withval=$with_aix_soname; case $withval in aix|svr4|both) ;; *) as_fn_error $? "Unknown argument to --with-aix-soname" "$LINENO" 5 ;; esac lt_cv_with_aix_soname=$with_aix_soname else $as_nop if test ${lt_cv_with_aix_soname+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_with_aix_soname=aix fi with_aix_soname=$lt_cv_with_aix_soname fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_aix_soname" >&5 printf "%s\n" "$with_aix_soname" >&6; } if test aix != "$with_aix_soname"; then # For the AIX way of multilib, we name the shared archive member # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o', # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File. # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag, # the AIX toolchain works better with OBJECT_MODE set (default 32). if test 64 = "${OBJECT_MODE-32}"; then shared_archive_member_spec=shr_64 else shared_archive_member_spec=shr fi fi ;; *) with_aix_soname=aix ;; esac # This can be used to rebuild libtool when needed LIBTOOL_DEPS=$ltmain # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' test -z "$LN_S" && LN_S="ln -s" if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 printf %s "checking for objdir... " >&6; } if test ${lt_cv_objdir+y} then : printf %s "(cached) " >&6 else $as_nop rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then lt_cv_objdir=.libs else # MS-DOS does not allow filenames that begin with a dot. lt_cv_objdir=_libs fi rmdir .libs 2>/dev/null fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 printf "%s\n" "$lt_cv_objdir" >&6; } objdir=$lt_cv_objdir printf "%s\n" "#define LT_OBJDIR \"$lt_cv_objdir/\"" >>confdefs.h case $host_os in aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # Global variables: ofile=libtool can_build_shared=yes # All known linkers require a '.a' archive for static linking (except MSVC and # ICC, which need '.lib'). libext=a with_gnu_ld=$lt_cv_prog_gnu_ld old_CC=$CC old_CFLAGS=$CFLAGS # Set sane defaults for various variables test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$LD" && LD=ld test -z "$ac_objext" && ac_objext=o func_cc_basename $compiler cc_basename=$func_cc_basename_result # Only perform the check for file, if the check method requires it test -z "$MAGIC_CMD" && MAGIC_CMD=file case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 printf %s "checking for ${ac_tool_prefix}file... " >&6; } if test ${lt_cv_path_MAGIC_CMD+y} then : printf %s "(cached) " >&6 else $as_nop case $MAGIC_CMD in [\\/*] | ?:[\\/]*) lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD=$MAGIC_CMD lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/${ac_tool_prefix}file"; then lt_cv_path_MAGIC_CMD=$ac_dir/"${ac_tool_prefix}file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD=$lt_cv_path_MAGIC_CMD if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS=$lt_save_ifs MAGIC_CMD=$lt_save_MAGIC_CMD ;; esac fi MAGIC_CMD=$lt_cv_path_MAGIC_CMD if test -n "$MAGIC_CMD"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 printf "%s\n" "$MAGIC_CMD" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for file" >&5 printf %s "checking for file... " >&6; } if test ${lt_cv_path_MAGIC_CMD+y} then : printf %s "(cached) " >&6 else $as_nop case $MAGIC_CMD in [\\/*] | ?:[\\/]*) lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD=$MAGIC_CMD lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/file"; then lt_cv_path_MAGIC_CMD=$ac_dir/"file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD=$lt_cv_path_MAGIC_CMD if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS=$lt_save_ifs MAGIC_CMD=$lt_save_MAGIC_CMD ;; esac fi MAGIC_CMD=$lt_cv_path_MAGIC_CMD if test -n "$MAGIC_CMD"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 printf "%s\n" "$MAGIC_CMD" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi else MAGIC_CMD=: fi fi fi ;; esac # Use C for the default configuration in the libtool script lt_save_CC=$CC ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu # Source file extension for C test sources. ac_ext=c # Object file extension for compiled C test sources. objext=o objext=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(){return(0);}' # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # Save the default compiler, since it gets overwritten when the other # tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. compiler_DEFAULT=$CC # save warnings/boilerplate of simple test code ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then lt_prog_compiler_no_builtin_flag= if test yes = "$GCC"; then case $cc_basename in nvcc*) lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; *) lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 printf %s "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } if test ${lt_cv_prog_compiler_rtti_exceptions+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_prog_compiler_rtti_exceptions=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-fno-rtti -fno-exceptions" ## exclude from sc_useless_quotes_in_assignment # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_rtti_exceptions=yes fi fi $RM conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 printf "%s\n" "$lt_cv_prog_compiler_rtti_exceptions" >&6; } if test yes = "$lt_cv_prog_compiler_rtti_exceptions"; then lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" else : fi fi lt_prog_compiler_wl= lt_prog_compiler_pic= lt_prog_compiler_static= if test yes = "$GCC"; then lt_prog_compiler_wl='-Wl,' lt_prog_compiler_static='-static' case $host_os in aix*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' fi lt_prog_compiler_pic='-fPIC' ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support lt_prog_compiler_pic='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the '-m68020' flag to GCC prevents building anything better, # like '-m68040'. lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries lt_prog_compiler_pic='-DDLL_EXPORT' case $host_os in os2*) lt_prog_compiler_static='$wl-static' ;; esac ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic='-fno-common' ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. lt_prog_compiler_static= ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) # +Z the default ;; *) lt_prog_compiler_pic='-fPIC' ;; esac ;; interix[3-9]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. lt_prog_compiler_can_build_shared=no enable_shared=no ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic='-fPIC -shared' ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic=-Kconform_pic fi ;; *) lt_prog_compiler_pic='-fPIC' ;; esac case $cc_basename in nvcc*) # Cuda Compiler Driver 2.2 lt_prog_compiler_wl='-Xlinker ' if test -n "$lt_prog_compiler_pic"; then lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic" fi ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) lt_prog_compiler_wl='-Wl,' if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' else lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' fi ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic='-fno-common' case $cc_basename in nagfor*) # NAG Fortran compiler lt_prog_compiler_wl='-Wl,-Wl,,' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; esac ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). lt_prog_compiler_pic='-DDLL_EXPORT' case $host_os in os2*) lt_prog_compiler_static='$wl-static' ;; esac ;; hpux9* | hpux10* | hpux11*) lt_prog_compiler_wl='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) lt_prog_compiler_pic='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? lt_prog_compiler_static='$wl-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) lt_prog_compiler_wl='-Wl,' # PIC (with -KPIC) is the default. lt_prog_compiler_static='-non_shared' ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in # old Intel for x86_64, which still supported -KPIC. ecc*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-static' ;; # flang / f18. f95 an alias for gfortran or flang on Debian flang* | f18* | f95*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; # Lahey Fortran 8.1. lf95*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='--shared' lt_prog_compiler_static='--static' ;; nagfor*) # NAG Fortran compiler lt_prog_compiler_wl='-Wl,-Wl,,' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; tcc*) # Fabrice Bellard et al's Tiny C Compiler lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fpic' lt_prog_compiler_static='-Bstatic' ;; ccc*) lt_prog_compiler_wl='-Wl,' # All Alpha code is PIC. lt_prog_compiler_static='-non_shared' ;; xl* | bgxl* | bgf* | mpixl*) # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-qpic' lt_prog_compiler_static='-qstaticlink' ;; *) case `$CC -V 2>&1 | $SED 5q` in *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*) # Sun Fortran 8.3 passes all unrecognized flags to the linker lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='' ;; *Sun\ F* | *Sun*Fortran*) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='-Qoption ld ' ;; *Sun\ C*) # Sun C 5.9 lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='-Wl,' ;; *Intel*\ [CF]*Compiler*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; *Portland\ Group*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fpic' lt_prog_compiler_static='-Bstatic' ;; esac ;; esac ;; newsos6) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic='-fPIC -shared' ;; osf3* | osf4* | osf5*) lt_prog_compiler_wl='-Wl,' # All OSF/1 code is PIC. lt_prog_compiler_static='-non_shared' ;; rdos*) lt_prog_compiler_static='-non_shared' ;; solaris*) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' case $cc_basename in f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) lt_prog_compiler_wl='-Qoption ld ';; *) lt_prog_compiler_wl='-Wl,';; esac ;; sunos4*) lt_prog_compiler_wl='-Qoption ld ' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic='-Kconform_pic' lt_prog_compiler_static='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; unicos*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_can_build_shared=no ;; uts4*) lt_prog_compiler_pic='-pic' lt_prog_compiler_static='-Bstatic' ;; *) lt_prog_compiler_can_build_shared=no ;; esac fi case $host_os in # For platforms that do not support PIC, -DPIC is meaningless: *djgpp*) lt_prog_compiler_pic= ;; *) lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 printf %s "checking for $compiler option to produce PIC... " >&6; } if test ${lt_cv_prog_compiler_pic+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_prog_compiler_pic=$lt_prog_compiler_pic fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 printf "%s\n" "$lt_cv_prog_compiler_pic" >&6; } lt_prog_compiler_pic=$lt_cv_prog_compiler_pic # # Check to make sure the PIC flag actually works. # if test -n "$lt_prog_compiler_pic"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 printf %s "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } if test ${lt_cv_prog_compiler_pic_works+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_prog_compiler_pic_works=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$lt_prog_compiler_pic -DPIC" ## exclude from sc_useless_quotes_in_assignment # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_pic_works=yes fi fi $RM conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 printf "%s\n" "$lt_cv_prog_compiler_pic_works" >&6; } if test yes = "$lt_cv_prog_compiler_pic_works"; then case $lt_prog_compiler_pic in "" | " "*) ;; *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; esac else lt_prog_compiler_pic= lt_prog_compiler_can_build_shared=no fi fi # # Check to make sure the static flag actually works. # wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 printf %s "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } if test ${lt_cv_prog_compiler_static_works+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_prog_compiler_static_works=no save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS $lt_tmp_static_flag" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_static_works=yes fi else lt_cv_prog_compiler_static_works=yes fi fi $RM -r conftest* LDFLAGS=$save_LDFLAGS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 printf "%s\n" "$lt_cv_prog_compiler_static_works" >&6; } if test yes = "$lt_cv_prog_compiler_static_works"; then : else lt_prog_compiler_static= fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 printf %s "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if test ${lt_cv_prog_compiler_c_o+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_prog_compiler_c_o=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 printf "%s\n" "$lt_cv_prog_compiler_c_o" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 printf %s "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if test ${lt_cv_prog_compiler_c_o+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_prog_compiler_c_o=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 printf "%s\n" "$lt_cv_prog_compiler_c_o" >&6; } hard_links=nottested if test no = "$lt_cv_prog_compiler_c_o" && test no != "$need_locks"; then # do not overwrite the value of need_locks provided by the user { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 printf %s "checking if we can lock with hard links... " >&6; } hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 printf "%s\n" "$hard_links" >&6; } if test no = "$hard_links"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5 printf "%s\n" "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;} need_locks=warn fi else need_locks=no fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 printf %s "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } runpath_var= allow_undefined_flag= always_export_symbols=no archive_cmds= archive_expsym_cmds= compiler_needs_object=no enable_shared_with_static_runtimes=no export_dynamic_flag_spec= export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' hardcode_automatic=no hardcode_direct=no hardcode_direct_absolute=no hardcode_libdir_flag_spec= hardcode_libdir_separator= hardcode_minus_L=no hardcode_shlibpath_var=unsupported inherit_rpath=no link_all_deplibs=unknown module_cmds= module_expsym_cmds= old_archive_from_new_cmds= old_archive_from_expsyms_cmds= thread_safe_flag_spec= whole_archive_flag_spec= # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list include_expsyms= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ' (' and ')$', so one must not match beginning or # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc', # as well as any symbol that contains 'd'. exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. # Exclude shared library initialization/finalization symbols. extract_expsyms_cmds= case $host_os in cygwin* | mingw* | pw32* | cegcc*) # FIXME: the MSVC++ and ICC port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++ or Intel C++ Compiler. if test yes != "$GCC"; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++ or ICC) with_gnu_ld=yes ;; openbsd* | bitrig*) with_gnu_ld=no ;; linux* | k*bsd*-gnu | gnu*) link_all_deplibs=no ;; esac ld_shlibs=yes # On some targets, GNU ld is compatible enough with the native linker # that we're better off using the native interface for both. lt_use_gnu_ld_interface=no if test yes = "$with_gnu_ld"; then case $host_os in aix*) # The AIX port of GNU ld has always aspired to compatibility # with the native linker. However, as the warning in the GNU ld # block says, versions before 2.19.5* couldn't really create working # shared libraries, regardless of the interface used. case `$LD -v 2>&1` in *\ \(GNU\ Binutils\)\ 2.19.5*) ;; *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; *\ \(GNU\ Binutils\)\ [3-9]*) ;; *) lt_use_gnu_ld_interface=yes ;; esac ;; *) lt_use_gnu_ld_interface=yes ;; esac fi if test yes = "$lt_use_gnu_ld_interface"; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='$wl' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' export_dynamic_flag_spec='$wl--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then whole_archive_flag_spec=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' else whole_archive_flag_spec= fi supports_anon_versioning=no case `$LD -v | $SED -e 's/([^)]\+)\s\+//' 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac # See if GNU ld supports shared libraries. case $host_os in aix[3-9]*) # On AIX/PPC, the GNU linker is very broken if test ia64 != "$host_cpu"; then ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: the GNU linker, at least up to release 2.19, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to install binutils *** 2.20 or above, or modify your PATH so that a non-GNU linker is found. *** You will then need to restart the configuration process. _LT_EOF fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='' ;; m68k) archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; esac ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then allow_undefined_flag=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' else ld_shlibs=no fi ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, # as there is no search path for DLLs. hardcode_libdir_flag_spec='-L$libdir' export_dynamic_flag_spec='$wl--export-all-symbols' allow_undefined_flag=unsupported always_export_symbols=no enable_shared_with_static_runtimes=yes export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file, use it as # is; otherwise, prepend EXPORTS... archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else ld_shlibs=no fi ;; haiku*) archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' link_all_deplibs=yes ;; os2*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes allow_undefined_flag=unsupported shrext_cmds=.dll archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' enable_shared_with_static_runtimes=yes file_list_spec='@' ;; interix[3-9]*) hardcode_direct=no hardcode_shlibpath_var=no hardcode_libdir_flag_spec='$wl-rpath,$libdir' export_dynamic_flag_spec='$wl-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' archive_expsym_cmds='$SED "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) tmp_diet=no if test linux-dietlibc = "$host_os"; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ && test no = "$tmp_diet" then tmp_addflag=' $pic_flag' tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group f77 and f90 compilers whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; lf95*) # Lahey Fortran 8.1 whole_archive_flag_spec= tmp_sharedflag='--shared' ;; nagfor*) # NAGFOR 5.3 tmp_sharedflag='-Wl,-shared' ;; xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; nvcc*) # Cuda Compiler Driver 2.2 whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' compiler_needs_object=yes ;; esac case `$CC -V 2>&1 | $SED 5q` in *Sun\ C*) # Sun C 5.9 whole_archive_flag_spec='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' compiler_needs_object=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' if test yes = "$supports_anon_versioning"; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi case $cc_basename in tcc*) hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' export_dynamic_flag_spec='-rdynamic' ;; xlf* | bgf* | bgxlf* | mpixlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test yes = "$supports_anon_versioning"; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else ld_shlibs=no fi ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris*) if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF ;; *) # For security reasons, it is highly recommended that you always # use absolute paths for naming shared libraries, and exclude the # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; esac ;; sunos4*) archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= hardcode_direct=yes hardcode_shlibpath_var=no ;; *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; esac if test no = "$ld_shlibs"; then runpath_var= hardcode_libdir_flag_spec= export_dynamic_flag_spec= whole_archive_flag_spec= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) allow_undefined_flag=unsupported always_export_symbols=yes archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. hardcode_minus_L=yes if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. hardcode_direct=unsupported fi ;; aix[4-9]*) if test ia64 = "$host_cpu"; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag= else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to GNU nm, but means don't demangle to AIX nm. # Without the "-l" option, or with the "-B" option, AIX nm treats # weak defined symbols like other global defined symbols, whereas # GNU nm marks them as "W". # While the 'weak' keyword is ignored in the Export File, we need # it in the Import File for the 'aix-soname' feature, so we have # to replace the "-B" option with "-P" for AIX nm. if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else export_symbols_cmds='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # have runtime linking enabled, and use it for executables. # For shared libraries, we enable/disable runtime linking # depending on the kind of the shared library created - # when "with_aix_soname,aix_use_runtimelinking" is: # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables # "aix,yes" lib.so shared, rtl:yes, for executables # lib.a static archive # "both,no" lib.so.V(shr.o) shared, rtl:yes # lib.a(lib.so.V) shared, rtl:no, for executables # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a(lib.so.V) shared, rtl:no # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a static archive case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) for ld_flag in $LDFLAGS; do if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then aix_use_runtimelinking=yes break fi done if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then # With aix-soname=svr4, we create the lib.so.V shared archives only, # so we don't have lib.a shared libs to link our executables. # We have to force runtime linking in this case. aix_use_runtimelinking=yes LDFLAGS="$LDFLAGS -Wl,-brtl" fi ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. archive_cmds='' hardcode_direct=yes hardcode_direct_absolute=yes hardcode_libdir_separator=':' link_all_deplibs=yes file_list_spec='$wl-f,' case $with_aix_soname,$aix_use_runtimelinking in aix,*) ;; # traditional, no import file svr4,* | *,yes) # use import file # The Import File defines what to hardcode. hardcode_direct=no hardcode_direct_absolute=no ;; esac if test yes = "$GCC"; then case $host_os in aix4.[012]|aix4.[012].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`$CC -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 hardcode_direct=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking hardcode_minus_L=yes hardcode_libdir_flag_spec='-L$libdir' hardcode_libdir_separator= fi ;; esac shared_flag='-shared' if test yes = "$aix_use_runtimelinking"; then shared_flag="$shared_flag "'$wl-G' fi # Need to ensure runtime linking is disabled for the traditional # shared library, or the linker may eventually find shared libraries # /with/ Import File - we do not want to mix them. shared_flag_aix='-shared' shared_flag_svr4='-shared $wl-G' else # not using gcc if test ia64 = "$host_cpu"; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test yes = "$aix_use_runtimelinking"; then shared_flag='$wl-G' else shared_flag='$wl-bM:SRE' fi shared_flag_aix='$wl-bM:SRE' shared_flag_svr4='$wl-G' fi fi export_dynamic_flag_spec='$wl-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. always_export_symbols=yes if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. allow_undefined_flag='-berok' # Determine the default libpath from the value encoded in an # empty executable. if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else if test ${lt_cv_aix_libpath_+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=/usr/lib:/lib fi fi aix_libpath=$lt_cv_aix_libpath_ fi hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath" archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag else if test ia64 = "$host_cpu"; then hardcode_libdir_flag_spec='$wl-R $libdir:/usr/lib:/lib' allow_undefined_flag="-z nodefs" archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else if test ${lt_cv_aix_libpath_+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=/usr/lib:/lib fi fi aix_libpath=$lt_cv_aix_libpath_ fi hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. no_undefined_flag=' $wl-bernotok' allow_undefined_flag=' $wl-berok' if test yes = "$with_gnu_ld"; then # We only use this code for GNU lds that support --whole-archive. whole_archive_flag_spec='$wl--whole-archive$convenience $wl--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives whole_archive_flag_spec='$convenience' fi archive_cmds_need_lc=yes archive_expsym_cmds='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' # -brtl affects multiple linker settings, -berok does not and is overridden later compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`' if test svr4 != "$with_aix_soname"; then # This is similar to how AIX traditionally builds its shared libraries. archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' fi if test aix != "$with_aix_soname"; then archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' else # used by -dlpreopen to get the symbols archive_expsym_cmds="$archive_expsym_cmds"'~$MV $output_objdir/$realname.d/$soname $output_objdir' fi archive_expsym_cmds="$archive_expsym_cmds"'~$RM -r $output_objdir/$realname.d' fi fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='' ;; m68k) archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; esac ;; bsdi[45]*) export_dynamic_flag_spec=-rdynamic ;; cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++ or Intel C++ Compiler. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. case $cc_basename in cl* | icl*) # Native MSVC or ICC hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported always_export_symbols=yes file_list_spec='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then cp "$export_symbols" "$output_objdir/$soname.def"; echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; else $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, )='true' enable_shared_with_static_runtimes=yes exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' # Don't use ranlib old_postinstall_cmds='chmod 644 $oldlib' postlink_cmds='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile=$lt_outputfile.exe lt_tool_outputfile=$lt_tool_outputfile.exe ;; esac~ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # Assume MSVC and ICC wrapper hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. old_archive_from_new_cmds='true' # FIXME: Should let the user specify the lib program. old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' enable_shared_with_static_runtimes=yes ;; esac ;; darwin* | rhapsody*) archive_cmds_need_lc=no hardcode_direct=no hardcode_automatic=yes hardcode_shlibpath_var=unsupported if test yes = "$lt_cv_ld_force_load"; then whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' else whole_archive_flag_spec='' fi link_all_deplibs=yes allow_undefined_flag=$_lt_dar_allow_undefined case $cc_basename in ifort*|nagfor*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test yes = "$_lt_dar_can_shared"; then output_verbose_link_cmd=func_echo_all archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" archive_expsym_cmds="$SED 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" module_expsym_cmds="$SED -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" else ld_shlibs=no fi ;; dgux*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-L$libdir' hardcode_shlibpath_var=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2.*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes hardcode_minus_L=yes hardcode_shlibpath_var=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly* | midnightbsd*) archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; hpux9*) if test yes = "$GCC"; then archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' fi hardcode_libdir_flag_spec='$wl+b $wl$libdir' hardcode_libdir_separator=: hardcode_direct=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes export_dynamic_flag_spec='$wl-E' ;; hpux10*) if test yes,no = "$GCC,$with_gnu_ld"; then archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test no = "$with_gnu_ld"; then hardcode_libdir_flag_spec='$wl+b $wl$libdir' hardcode_libdir_separator=: hardcode_direct=yes hardcode_direct_absolute=yes export_dynamic_flag_spec='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes fi ;; hpux11*) if test yes,no = "$GCC,$with_gnu_ld"; then case $host_cpu in hppa*64*) archive_cmds='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) archive_cmds='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) # Older versions of the 11.00 compiler do not understand -b yet # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 printf %s "checking if $CC understands -b... " >&6; } if test ${lt_cv_prog_compiler__b+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_prog_compiler__b=no save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS -b" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler__b=yes fi else lt_cv_prog_compiler__b=yes fi fi $RM -r conftest* LDFLAGS=$save_LDFLAGS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 printf "%s\n" "$lt_cv_prog_compiler__b" >&6; } if test yes = "$lt_cv_prog_compiler__b"; then archive_cmds='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi ;; esac fi if test no = "$with_gnu_ld"; then hardcode_libdir_flag_spec='$wl+b $wl$libdir' hardcode_libdir_separator=: case $host_cpu in hppa*64*|ia64*) hardcode_direct=no hardcode_shlibpath_var=no ;; *) hardcode_direct=yes hardcode_direct_absolute=yes export_dynamic_flag_spec='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test yes = "$GCC"; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. # This should be the same for all languages, so no per-tag cache variable. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5 printf %s "checking whether the $host_os linker accepts -exported_symbol... " >&6; } if test ${lt_cv_irix_exported_symbol+y} then : printf %s "(cached) " >&6 else $as_nop save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int foo (void) { return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : lt_cv_irix_exported_symbol=yes else $as_nop lt_cv_irix_exported_symbol=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 printf "%s\n" "$lt_cv_irix_exported_symbol" >&6; } if test yes = "$lt_cv_irix_exported_symbol"; then archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' fi link_all_deplibs=no else archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' fi archive_cmds_need_lc='no' hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' hardcode_libdir_separator=: inherit_rpath=yes link_all_deplibs=yes ;; linux*) case $cc_basename in tcc*) # Fabrice Bellard et al's Tiny C Compiler ld_shlibs=yes archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' ;; esac ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; newsos6) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' hardcode_libdir_separator=: hardcode_shlibpath_var=no ;; *nto* | *qnx*) ;; openbsd* | bitrig*) if test -f /usr/libexec/ld.so; then hardcode_direct=yes hardcode_shlibpath_var=no hardcode_direct_absolute=yes if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols' hardcode_libdir_flag_spec='$wl-rpath,$libdir' export_dynamic_flag_spec='$wl-E' else archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='$wl-rpath,$libdir' fi else ld_shlibs=no fi ;; os2*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes allow_undefined_flag=unsupported shrext_cmds=.dll archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' enable_shared_with_static_runtimes=yes file_list_spec='@' ;; osf3*) if test yes = "$GCC"; then allow_undefined_flag=' $wl-expect_unresolved $wl\*' archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' else allow_undefined_flag=' -expect_unresolved \*' archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' fi archive_cmds_need_lc='no' hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' hardcode_libdir_separator=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test yes = "$GCC"; then allow_undefined_flag=' $wl-expect_unresolved $wl\*' archive_cmds='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' else allow_undefined_flag=' -expect_unresolved \*' archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp' # Both c and cxx compiler support -rpath directly hardcode_libdir_flag_spec='-rpath $libdir' fi archive_cmds_need_lc='no' hardcode_libdir_separator=: ;; solaris*) no_undefined_flag=' -z defs' if test yes = "$GCC"; then wlarc='$wl' archive_cmds='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' archive_cmds='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) wlarc='$wl' archive_cmds='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi hardcode_libdir_flag_spec='-R$libdir' hardcode_shlibpath_var=no case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands '-z linker_flag'. GCC discards it without '$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) if test yes = "$GCC"; then whole_archive_flag_spec='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' else whole_archive_flag_spec='-z allextract$convenience -z defaultextract' fi ;; esac link_all_deplibs=yes ;; sunos4*) if test sequent = "$host_vendor"; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. archive_cmds='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi hardcode_libdir_flag_spec='-L$libdir' hardcode_direct=yes hardcode_minus_L=yes hardcode_shlibpath_var=no ;; sysv4) case $host_vendor in sni) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' reload_cmds='$CC -r -o $output$reload_objs' hardcode_direct=no ;; motorola) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' hardcode_shlibpath_var=no ;; sysv4.3*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var=no export_dynamic_flag_spec='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes ld_shlibs=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) no_undefined_flag='$wl-z,text' archive_cmds_need_lc=no hardcode_shlibpath_var=no runpath_var='LD_RUN_PATH' if test yes = "$GCC"; then archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We CANNOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. no_undefined_flag='$wl-z,text' allow_undefined_flag='$wl-z,nodefs' archive_cmds_need_lc=no hardcode_shlibpath_var=no hardcode_libdir_flag_spec='$wl-R,$libdir' hardcode_libdir_separator=':' link_all_deplibs=yes export_dynamic_flag_spec='$wl-Bexport' runpath_var='LD_RUN_PATH' if test yes = "$GCC"; then archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-L$libdir' hardcode_shlibpath_var=no ;; *) ld_shlibs=no ;; esac if test sni = "$host_vendor"; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) export_dynamic_flag_spec='$wl-Blargedynsym' ;; esac fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 printf "%s\n" "$ld_shlibs" >&6; } test no = "$ld_shlibs" && can_build_shared=no with_gnu_ld=$with_gnu_ld # # Do we need to explicitly link libc? # case "x$archive_cmds_need_lc" in x|xyes) # Assume -lc should be added archive_cmds_need_lc=yes if test yes,yes = "$GCC,$enable_shared"; then case $archive_cmds in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 printf %s "checking whether -lc should be explicitly linked in... " >&6; } if test ${lt_cv_archive_cmds_need_lc+y} then : printf %s "(cached) " >&6 else $as_nop $RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$lt_prog_compiler_wl pic_flag=$lt_prog_compiler_pic compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$allow_undefined_flag allow_undefined_flag= if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then lt_cv_archive_cmds_need_lc=no else lt_cv_archive_cmds_need_lc=yes fi allow_undefined_flag=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 printf "%s\n" "$lt_cv_archive_cmds_need_lc" >&6; } archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc ;; esac fi ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 printf %s "checking dynamic linker characteristics... " >&6; } if test yes = "$GCC"; then case $host_os in darwin*) lt_awk_arg='/^libraries:/,/LR/' ;; *) lt_awk_arg='/^libraries:/' ;; esac case $host_os in mingw* | cegcc*) lt_sed_strip_eq='s|=\([A-Za-z]:\)|\1|g' ;; *) lt_sed_strip_eq='s|=/|/|g' ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` case $lt_search_path_spec in *\;*) # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` ;; *) lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` ;; esac # Ok, now we have the path, separated by spaces, we can step through it # and add multilib dir if necessary... lt_tmp_lt_search_path_spec= lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` # ...but if some path component already ends with the multilib dir we assume # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer). case "$lt_multi_os_dir; $lt_search_path_spec " in "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*) lt_multi_os_dir= ;; esac for lt_sys_path in $lt_search_path_spec; do if test -d "$lt_sys_path$lt_multi_os_dir"; then lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir" elif test -n "$lt_multi_os_dir"; then test -d "$lt_sys_path" && \ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" fi done lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' BEGIN {RS = " "; FS = "/|\n";} { lt_foo = ""; lt_count = 0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { lt_foo = "/" $lt_i lt_foo; } else { lt_count--; } } } } if (lt_foo != "") { lt_freq[lt_foo]++; } if (lt_freq[lt_foo] == 1) { print lt_foo; } }'` # AWK program above erroneously prepends '/' to C:/dos/paths # for these hosts. case $host_os in mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ $SED 's|/\([A-Za-z]:\)|\1|g'` ;; esac sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=.so postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='$libname$release$shared_ext$major' ;; aix[4-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes if test ia64 = "$host_cpu"; then # AIX 5 supports IA64 library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line '#! .'. This would cause the generated library to # depend on '.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[01] | aix4.[01].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # Using Import Files as archive members, it is possible to support # filename-based versioning of shared library archives on AIX. While # this would work for both with and without runtime linking, it will # prevent static linking of such archives. So we do filename-based # shared library versioning with .so extension only, which is used # when both runtime linking and shared linking is enabled. # Unfortunately, runtime linking may impact performance, so we do # not want this to be the default eventually. Also, we use the # versioned .so libs for executables only if there is the -brtl # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. # To allow for filename-based versioning support, we need to create # libNAME.so.V as an archive file, containing: # *) an Import File, referring to the versioned filename of the # archive as well as the shared archive member, telling the # bitwidth (32 or 64) of that shared object, and providing the # list of exported symbols of that shared object, eventually # decorated with the 'weak' keyword # *) the shared object with the F_LOADONLY flag set, to really avoid # it being seen by the linker. # At run time we better use the real file rather than another symlink, # but for link time we create the symlink libNAME.so -> libNAME.so.V case $with_aix_soname,$aix_use_runtimelinking in # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. aix,yes) # traditional libtool dynamic_linker='AIX unversionable lib.so' # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; aix,no) # traditional AIX only dynamic_linker='AIX lib.a(lib.so.V)' # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' ;; svr4,*) # full svr4 only dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,yes) # both, prefer svr4 dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # unpreferred sharedlib libNAME.a needs extra handling postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,no) # both, prefer aix dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)" library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' ;; esac shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='$libname$shared_ext' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[45]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no case $GCC,$cc_basename in yes,*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo $libname | $SED -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo $libname | $SED -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' ;; esac dynamic_linker='Win32 ld.exe' ;; *,cl* | *,icl*) # Native MSVC or ICC libname_spec='$name' soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' library_names_spec='$libname.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec=$LIB if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC and ICC wrapper library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' soname_spec='$libname$release$major$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd* | dragonfly* | midnightbsd*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[23].*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2.*) shlibpath_overrides_runpath=yes ;; freebsd3.[01]* | freebsdelf3.[01]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=no sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' if test 32 = "$HPUX_IA64_MODE"; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" sys_lib_dlsearch_path_spec=/usr/lib/hpux32 else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" sys_lib_dlsearch_path_spec=/usr/lib/hpux64 fi ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... postinstall_cmds='chmod 555 $lib' # or fails outright, so override atomically: install_override_mode=555 ;; interix[3-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test yes = "$lt_cv_prog_gnu_ld"; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; linux*android*) version_type=none # Android doesn't support versioned libraries. need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext' soname_spec='$libname$release$shared_ext' finish_cmds= shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes dynamic_linker='Android linker' # Don't embed -rpath directories since the linker doesn't support them. hardcode_libdir_flag_spec='-L$libdir' ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH if test ${lt_cv_shlibpath_overrides_runpath+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null then : lt_cv_shlibpath_overrides_runpath=yes fi fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS libdir=$save_libdir fi shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Ideally, we could use ldconfig to report *all* directores which are # searched for libraries, however this is still not possible. Aside from not # being certain /sbin/ldconfig is available, command # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, # even though it is searched at run-time. Try to do the best guess by # appending ld.so.conf contents (and includes) to the search path. if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsdelf*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='NetBSD ld.elf_so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd* | bitrig*) version_type=sunos sys_lib_dlsearch_path_spec=/usr/lib need_lib_prefix=no if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then need_version=no else need_version=yes fi library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; os2*) libname_spec='$name' version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no # OS/2 can only load a DLL with a base name of 8 characters or less. soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; v=$($ECHO $release$versuffix | tr -d .-); n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); $ECHO $n$v`$shared_ext' library_names_spec='${libname}_dll.$libext' dynamic_linker='OS/2 ld.exe' shlibpath_var=BEGINLIBPATH sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test yes = "$with_gnu_ld"; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec; then version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' soname_spec='$libname$shared_ext.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=sco need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test yes = "$with_gnu_ld"; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 printf "%s\n" "$dynamic_linker" >&6; } test no = "$dynamic_linker" && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test yes = "$GCC"; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec fi if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec fi # remember unaugmented sys_lib_dlsearch_path content for libtool script decls... configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec # ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" # to be used as default LT_SYS_LIBRARY_PATH value in generated libtool configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 printf %s "checking how to hardcode library paths into programs... " >&6; } hardcode_action= if test -n "$hardcode_libdir_flag_spec" || test -n "$runpath_var" || test yes = "$hardcode_automatic"; then # We can hardcode non-existent directories. if test no != "$hardcode_direct" && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, )" && test no != "$hardcode_minus_L"; then # Linking always hardcodes the temporary library directory. hardcode_action=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. hardcode_action=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. hardcode_action=unsupported fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 printf "%s\n" "$hardcode_action" >&6; } if test relink = "$hardcode_action" || test yes = "$inherit_rpath"; then # Fast installation is not supported enable_fast_install=no elif test yes = "$shlibpath_overrides_runpath" || test no = "$enable_shared"; then # Fast installation is not necessary enable_fast_install=needless fi if test yes != "$enable_dlopen"; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown else lt_cv_dlopen=no lt_cv_dlopen_libs= case $host_os in beos*) lt_cv_dlopen=load_add_on lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32* | cegcc*) lt_cv_dlopen=LoadLibrary lt_cv_dlopen_libs= ;; cygwin*) lt_cv_dlopen=dlopen lt_cv_dlopen_libs= ;; darwin*) # if libdl is installed we need to link against it { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 printf %s "checking for dlopen in -ldl... " >&6; } if test ${ac_cv_lib_dl_dlopen+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char dlopen (); int main (void) { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_dl_dlopen=yes else $as_nop ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 printf "%s\n" "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes then : lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl else $as_nop lt_cv_dlopen=dyld lt_cv_dlopen_libs= lt_cv_dlopen_self=yes fi ;; tpf*) # Don't try to run any link tests for TPF. We know it's impossible # because TPF is a cross-compiler, and we know how we open DSOs. lt_cv_dlopen=dlopen lt_cv_dlopen_libs= lt_cv_dlopen_self=no ;; *) ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" if test "x$ac_cv_func_shl_load" = xyes then : lt_cv_dlopen=shl_load else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 printf %s "checking for shl_load in -ldld... " >&6; } if test ${ac_cv_lib_dld_shl_load+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char shl_load (); int main (void) { return shl_load (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_dld_shl_load=yes else $as_nop ac_cv_lib_dld_shl_load=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 printf "%s\n" "$ac_cv_lib_dld_shl_load" >&6; } if test "x$ac_cv_lib_dld_shl_load" = xyes then : lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld else $as_nop ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" if test "x$ac_cv_func_dlopen" = xyes then : lt_cv_dlopen=dlopen else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 printf %s "checking for dlopen in -ldl... " >&6; } if test ${ac_cv_lib_dl_dlopen+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char dlopen (); int main (void) { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_dl_dlopen=yes else $as_nop ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 printf "%s\n" "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes then : lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 printf %s "checking for dlopen in -lsvld... " >&6; } if test ${ac_cv_lib_svld_dlopen+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lsvld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char dlopen (); int main (void) { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_svld_dlopen=yes else $as_nop ac_cv_lib_svld_dlopen=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 printf "%s\n" "$ac_cv_lib_svld_dlopen" >&6; } if test "x$ac_cv_lib_svld_dlopen" = xyes then : lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 printf %s "checking for dld_link in -ldld... " >&6; } if test ${ac_cv_lib_dld_dld_link+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char dld_link (); int main (void) { return dld_link (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_dld_dld_link=yes else $as_nop ac_cv_lib_dld_dld_link=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 printf "%s\n" "$ac_cv_lib_dld_dld_link" >&6; } if test "x$ac_cv_lib_dld_dld_link" = xyes then : lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld fi fi fi fi fi fi ;; esac if test no = "$lt_cv_dlopen"; then enable_dlopen=no else enable_dlopen=yes fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS=$CPPFLAGS test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS=$LDFLAGS wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS=$LIBS LIBS="$lt_cv_dlopen_libs $LIBS" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 printf %s "checking whether a program can dlopen itself... " >&6; } if test ${lt_cv_dlopen_self+y} then : printf %s "(cached) " >&6 else $as_nop if test yes = "$cross_compiling"; then : lt_cv_dlopen_self=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF #line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisibility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; } _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; esac else : # compilation failed lt_cv_dlopen_self=no fi fi rm -fr conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 printf "%s\n" "$lt_cv_dlopen_self" >&6; } if test yes = "$lt_cv_dlopen_self"; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 printf %s "checking whether a statically linked program can dlopen itself... " >&6; } if test ${lt_cv_dlopen_self_static+y} then : printf %s "(cached) " >&6 else $as_nop if test yes = "$cross_compiling"; then : lt_cv_dlopen_self_static=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF #line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisibility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; } _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; esac else : # compilation failed lt_cv_dlopen_self_static=no fi fi rm -fr conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 printf "%s\n" "$lt_cv_dlopen_self_static" >&6; } fi CPPFLAGS=$save_CPPFLAGS LDFLAGS=$save_LDFLAGS LIBS=$save_LIBS ;; esac case $lt_cv_dlopen_self in yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; *) enable_dlopen_self=unknown ;; esac case $lt_cv_dlopen_self_static in yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; *) enable_dlopen_self_static=unknown ;; esac fi striplib= old_striplib= { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 printf %s "checking whether stripping libraries is possible... " >&6; } if test -z "$STRIP"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } else if $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then old_striplib="$STRIP --strip-debug" striplib="$STRIP --strip-unneeded" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else case $host_os in darwin*) # FIXME - insert some real tests, host_os isn't really good enough striplib="$STRIP -x" old_striplib="$STRIP -S" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } ;; freebsd*) if $STRIP -V 2>&1 | $GREP "elftoolchain" >/dev/null; then old_striplib="$STRIP --strip-debug" striplib="$STRIP --strip-unneeded" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi ;; *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } ;; esac fi fi # Report what library types will actually be built { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 printf %s "checking if libtool supports shared libraries... " >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 printf "%s\n" "$can_build_shared" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 printf %s "checking whether to build shared libraries... " >&6; } test no = "$can_build_shared" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[4-9]*) if test ia64 != "$host_cpu"; then case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in yes,aix,yes) ;; # shared object as lib.so file only yes,svr4,*) ;; # shared object as lib.so archive member only yes,*) enable_static=no ;; # shared object in lib.a archive as well esac fi ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 printf "%s\n" "$enable_shared" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 printf %s "checking whether to build static libraries... " >&6; } # Make sure either enable_shared or enable_static is yes. test yes = "$enable_shared" || enable_static=yes { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 printf "%s\n" "$enable_static" >&6; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu CC=$lt_save_CC ac_config_commands="$ac_config_commands libtool" # Only expand once: ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 printf "%s\n" "$ac_ct_CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then if test "$as_dir$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 printf "%s\n" "$ac_ct_CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}clang", so it can be a program name with args. set dummy ${ac_tool_prefix}clang; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}clang" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "clang", so it can be a program name with args. set dummy clang; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="clang" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 printf "%s\n" "$ac_ct_CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi fi test -z "$CC" && { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion -version; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports GNU C" >&5 printf %s "checking whether the compiler supports GNU C... " >&6; } if test ${ac_cv_c_compiler_gnu+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_compiler_gnu=yes else $as_nop ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 printf "%s\n" "$ac_cv_c_compiler_gnu" >&6; } ac_compiler_gnu=$ac_cv_c_compiler_gnu if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+y} ac_save_CFLAGS=$CFLAGS { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 printf %s "checking whether $CC accepts -g... " >&6; } if test ${ac_cv_prog_cc_g+y} then : printf %s "(cached) " >&6 else $as_nop ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_g=yes else $as_nop CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : else $as_nop ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 printf "%s\n" "$ac_cv_prog_cc_g" >&6; } if test $ac_test_CFLAGS; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi ac_prog_cc_stdc=no if test x$ac_prog_cc_stdc = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C11 features" >&5 printf %s "checking for $CC option to enable C11 features... " >&6; } if test ${ac_cv_prog_cc_c11+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_prog_cc_c11=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_c_conftest_c11_program _ACEOF for ac_arg in '' -std=gnu11 do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_c11=$ac_arg fi rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cc_c11" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi if test "x$ac_cv_prog_cc_c11" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } else $as_nop if test "x$ac_cv_prog_cc_c11" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c11" >&5 printf "%s\n" "$ac_cv_prog_cc_c11" >&6; } CC="$CC $ac_cv_prog_cc_c11" fi ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c11 ac_prog_cc_stdc=c11 fi fi if test x$ac_prog_cc_stdc = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C99 features" >&5 printf %s "checking for $CC option to enable C99 features... " >&6; } if test ${ac_cv_prog_cc_c99+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_prog_cc_c99=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_c_conftest_c99_program _ACEOF for ac_arg in '' -std=gnu99 -std=c99 -c99 -qlanglvl=extc1x -qlanglvl=extc99 -AC99 -D_STDC_C99= do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_c99=$ac_arg fi rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cc_c99" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi if test "x$ac_cv_prog_cc_c99" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } else $as_nop if test "x$ac_cv_prog_cc_c99" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5 printf "%s\n" "$ac_cv_prog_cc_c99" >&6; } CC="$CC $ac_cv_prog_cc_c99" fi ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99 ac_prog_cc_stdc=c99 fi fi if test x$ac_prog_cc_stdc = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C89 features" >&5 printf %s "checking for $CC option to enable C89 features... " >&6; } if test ${ac_cv_prog_cc_c89+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_c_conftest_c89_program _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi if test "x$ac_cv_prog_cc_c89" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } else $as_nop if test "x$ac_cv_prog_cc_c89" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 printf "%s\n" "$ac_cv_prog_cc_c89" >&6; } CC="$CC $ac_cv_prog_cc_c89" fi ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89 ac_prog_cc_stdc=c89 fi fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 printf %s "checking whether $CC understands -c and -o together... " >&6; } if test ${am_cv_prog_cc_c_o+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF # Make sure it works both with $CC and with simple cc. # Following AC_PROG_CC_C_O, we do the test twice because some # compilers refuse to overwrite an existing .o file with -o, # though they will create one. am_cv_prog_cc_c_o=yes for am_i in 1 2; do if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } \ && test -f conftest2.$ac_objext; then : OK else am_cv_prog_cc_c_o=no break fi done rm -f core conftest* unset am_i fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 printf "%s\n" "$am_cv_prog_cc_c_o" >&6; } if test "$am_cv_prog_cc_c_o" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu depcc="$CC" am_compiler_list= { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 printf %s "checking dependency style of $depcc... " >&6; } if test ${am_cv_CC_dependencies_compiler_type+y} then : printf %s "(cached) " >&6 else $as_nop if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CC_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 printf "%s\n" "$am_cv_CC_dependencies_compiler_type" >&6; } CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu if test -z "$CXX"; then if test -n "$CCC"; then CXX=$CCC else if test -n "$ac_tool_prefix"; then for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC clang++ do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CXX+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$CXX"; then ac_cv_prog_CXX="$CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CXX=$ac_cv_prog_CXX if test -n "$CXX"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 printf "%s\n" "$CXX" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$CXX" && break done fi if test -z "$CXX"; then ac_ct_CXX=$CXX for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC clang++ do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_CXX+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_CXX"; then ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CXX="$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CXX=$ac_cv_prog_ac_ct_CXX if test -n "$ac_ct_CXX"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 printf "%s\n" "$ac_ct_CXX" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$ac_ct_CXX" && break done if test "x$ac_ct_CXX" = x; then CXX="g++" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CXX=$ac_ct_CXX fi fi fi fi # Provide some information about the compiler. printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports GNU C++" >&5 printf %s "checking whether the compiler supports GNU C++... " >&6; } if test ${ac_cv_cxx_compiler_gnu+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : ac_compiler_gnu=yes else $as_nop ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_cv_cxx_compiler_gnu=$ac_compiler_gnu fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 printf "%s\n" "$ac_cv_cxx_compiler_gnu" >&6; } ac_compiler_gnu=$ac_cv_cxx_compiler_gnu if test $ac_compiler_gnu = yes; then GXX=yes else GXX= fi ac_test_CXXFLAGS=${CXXFLAGS+y} ac_save_CXXFLAGS=$CXXFLAGS { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 printf %s "checking whether $CXX accepts -g... " >&6; } if test ${ac_cv_prog_cxx_g+y} then : printf %s "(cached) " >&6 else $as_nop ac_save_cxx_werror_flag=$ac_cxx_werror_flag ac_cxx_werror_flag=yes ac_cv_prog_cxx_g=no CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : ac_cv_prog_cxx_g=yes else $as_nop CXXFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : else $as_nop ac_cxx_werror_flag=$ac_save_cxx_werror_flag CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : ac_cv_prog_cxx_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_cxx_werror_flag=$ac_save_cxx_werror_flag fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 printf "%s\n" "$ac_cv_prog_cxx_g" >&6; } if test $ac_test_CXXFLAGS; then CXXFLAGS=$ac_save_CXXFLAGS elif test $ac_cv_prog_cxx_g = yes; then if test "$GXX" = yes; then CXXFLAGS="-g -O2" else CXXFLAGS="-g" fi else if test "$GXX" = yes; then CXXFLAGS="-O2" else CXXFLAGS= fi fi ac_prog_cxx_stdcxx=no if test x$ac_prog_cxx_stdcxx = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CXX option to enable C++11 features" >&5 printf %s "checking for $CXX option to enable C++11 features... " >&6; } if test ${ac_cv_prog_cxx_cxx11+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_prog_cxx_cxx11=no ac_save_CXX=$CXX cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_cxx_conftest_cxx11_program _ACEOF for ac_arg in '' -std=gnu++11 -std=gnu++0x -std=c++11 -std=c++0x -qlanglvl=extended0x -AA do CXX="$ac_save_CXX $ac_arg" if ac_fn_cxx_try_compile "$LINENO" then : ac_cv_prog_cxx_cxx11=$ac_arg fi rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cxx_cxx11" != "xno" && break done rm -f conftest.$ac_ext CXX=$ac_save_CXX fi if test "x$ac_cv_prog_cxx_cxx11" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } else $as_nop if test "x$ac_cv_prog_cxx_cxx11" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_cxx11" >&5 printf "%s\n" "$ac_cv_prog_cxx_cxx11" >&6; } CXX="$CXX $ac_cv_prog_cxx_cxx11" fi ac_cv_prog_cxx_stdcxx=$ac_cv_prog_cxx_cxx11 ac_prog_cxx_stdcxx=cxx11 fi fi if test x$ac_prog_cxx_stdcxx = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CXX option to enable C++98 features" >&5 printf %s "checking for $CXX option to enable C++98 features... " >&6; } if test ${ac_cv_prog_cxx_cxx98+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_prog_cxx_cxx98=no ac_save_CXX=$CXX cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_cxx_conftest_cxx98_program _ACEOF for ac_arg in '' -std=gnu++98 -std=c++98 -qlanglvl=extended -AA do CXX="$ac_save_CXX $ac_arg" if ac_fn_cxx_try_compile "$LINENO" then : ac_cv_prog_cxx_cxx98=$ac_arg fi rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cxx_cxx98" != "xno" && break done rm -f conftest.$ac_ext CXX=$ac_save_CXX fi if test "x$ac_cv_prog_cxx_cxx98" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } else $as_nop if test "x$ac_cv_prog_cxx_cxx98" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_cxx98" >&5 printf "%s\n" "$ac_cv_prog_cxx_cxx98" >&6; } CXX="$CXX $ac_cv_prog_cxx_cxx98" fi ac_cv_prog_cxx_stdcxx=$ac_cv_prog_cxx_cxx98 ac_prog_cxx_stdcxx=cxx98 fi fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu depcc="$CXX" am_compiler_list= { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 printf %s "checking dependency style of $depcc... " >&6; } if test ${am_cv_CXX_dependencies_compiler_type+y} then : printf %s "(cached) " >&6 else $as_nop if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CXX_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CXX_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CXX_dependencies_compiler_type=none fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5 printf "%s\n" "$am_cv_CXX_dependencies_compiler_type" >&6; } CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then am__fastdepCXX_TRUE= am__fastdepCXX_FALSE='#' else am__fastdepCXX_TRUE='#' am__fastdepCXX_FALSE= fi func_stripname_cnf () { case $2 in .*) func_stripname_result=`$ECHO "$3" | $SED "s%^$1%%; s%\\\\$2\$%%"`;; *) func_stripname_result=`$ECHO "$3" | $SED "s%^$1%%; s%$2\$%%"`;; esac } # func_stripname_cnf if test -n "$CXX" && ( test no != "$CXX" && ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) || (test g++ != "$CXX"))); then ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 printf %s "checking how to run the C++ preprocessor... " >&6; } if test -z "$CXXCPP"; then if test ${ac_cv_prog_CXXCPP+y} then : printf %s "(cached) " >&6 else $as_nop # Double quotes because $CXX needs to be expanded for CXXCPP in "$CXX -E" cpp /lib/cpp do ac_preproc_ok=false for ac_cxx_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include Syntax error _ACEOF if ac_fn_cxx_try_cpp "$LINENO" then : else $as_nop # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_cxx_try_cpp "$LINENO" then : # Broken: success on invalid input. continue else $as_nop # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok then : break fi done ac_cv_prog_CXXCPP=$CXXCPP fi CXXCPP=$ac_cv_prog_CXXCPP else ac_cv_prog_CXXCPP=$CXXCPP fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5 printf "%s\n" "$CXXCPP" >&6; } ac_preproc_ok=false for ac_cxx_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include Syntax error _ACEOF if ac_fn_cxx_try_cpp "$LINENO" then : else $as_nop # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_cxx_try_cpp "$LINENO" then : # Broken: success on invalid input. continue else $as_nop # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok then : else $as_nop { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu else _lt_caught_CXX_error=yes fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu archive_cmds_need_lc_CXX=no allow_undefined_flag_CXX= always_export_symbols_CXX=no archive_expsym_cmds_CXX= compiler_needs_object_CXX=no export_dynamic_flag_spec_CXX= hardcode_direct_CXX=no hardcode_direct_absolute_CXX=no hardcode_libdir_flag_spec_CXX= hardcode_libdir_separator_CXX= hardcode_minus_L_CXX=no hardcode_shlibpath_var_CXX=unsupported hardcode_automatic_CXX=no inherit_rpath_CXX=no module_cmds_CXX= module_expsym_cmds_CXX= link_all_deplibs_CXX=unknown old_archive_cmds_CXX=$old_archive_cmds reload_flag_CXX=$reload_flag reload_cmds_CXX=$reload_cmds no_undefined_flag_CXX= whole_archive_flag_spec_CXX= enable_shared_with_static_runtimes_CXX=no # Source file extension for C++ test sources. ac_ext=cpp # Object file extension for compiled C++ test sources. objext=o objext_CXX=$objext # No sense in running all these tests if we already determined that # the CXX compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test yes != "$_lt_caught_CXX_error"; then # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(int, char *[]) { return(0); }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # save warnings/boilerplate of simple test code ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_LD=$LD lt_save_GCC=$GCC GCC=$GXX lt_save_with_gnu_ld=$with_gnu_ld lt_save_path_LD=$lt_cv_path_LD if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx else $as_unset lt_cv_prog_gnu_ld fi if test -n "${lt_cv_path_LDCXX+set}"; then lt_cv_path_LD=$lt_cv_path_LDCXX else $as_unset lt_cv_path_LD fi test -z "${LDCXX+set}" || LD=$LDCXX CC=${CXX-"c++"} CFLAGS=$CXXFLAGS compiler=$CC compiler_CXX=$CC func_cc_basename $compiler cc_basename=$func_cc_basename_result if test -n "$compiler"; then # We don't want -fno-exception when compiling C++ code, so set the # no_builtin_flag separately if test yes = "$GXX"; then lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin' else lt_prog_compiler_no_builtin_flag_CXX= fi if test yes = "$GXX"; then # Set up default GNU C++ configuration # Check whether --with-gnu-ld was given. if test ${with_gnu_ld+y} then : withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes else $as_nop with_gnu_ld=no fi ac_prog=ld if test yes = "$GCC"; then # Check if gcc -print-prog-name=ld gives a path. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 printf %s "checking for ld used by $CC... " >&6; } case $host in *-*-mingw*) # gcc leaves a trailing carriage return, which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [\\/]* | ?:[\\/]*) re_direlt='/[^/][^/]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD=$ac_prog ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test yes = "$with_gnu_ld"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 printf %s "checking for GNU ld... " >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 printf %s "checking for non-GNU ld... " >&6; } fi if test ${lt_cv_path_LD+y} then : printf %s "(cached) " >&6 else $as_nop if test -z "$LD"; then lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD=$ac_dir/$ac_prog # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &5 printf "%s\n" "$LD" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 printf %s "checking if the linker ($LD) is GNU ld... " >&6; } if test ${lt_cv_prog_gnu_ld+y} then : printf %s "(cached) " >&6 else $as_nop # I'd rather use --version here, but apparently some GNU lds only accept -v. case `$LD -v 2>&1 &5 printf "%s\n" "$lt_cv_prog_gnu_ld" >&6; } with_gnu_ld=$lt_cv_prog_gnu_ld # Check if GNU C++ uses GNU ld as the underlying linker, since the # archiving commands below assume that GNU ld is being used. if test yes = "$with_gnu_ld"; then archive_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' export_dynamic_flag_spec_CXX='$wl--export-dynamic' # If archive_cmds runs LD, not CC, wlarc should be empty # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to # investigate it a little bit more. (MM) wlarc='$wl' # ancient GNU ld didn't support --whole-archive et. al. if eval "`$CC -print-prog-name=ld` --help 2>&1" | $GREP 'no-whole-archive' > /dev/null; then whole_archive_flag_spec_CXX=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' else whole_archive_flag_spec_CXX= fi else with_gnu_ld=no wlarc= # A generic and very simple default shared library creation # command for GNU C++ for the case where it uses the native # linker, instead of GNU ld. If possible, this setting should # overridden to take advantage of the native linker features on # the platform it is being used on. archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' fi # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' else GXX=no with_gnu_ld=no wlarc= fi # PORTME: fill in a description of your system's C++ link characteristics { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 printf %s "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } ld_shlibs_CXX=yes case $host_os in aix3*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; aix[4-9]*) if test ia64 = "$host_cpu"; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag= else aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # have runtime linking enabled, and use it for executables. # For shared libraries, we enable/disable runtime linking # depending on the kind of the shared library created - # when "with_aix_soname,aix_use_runtimelinking" is: # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables # "aix,yes" lib.so shared, rtl:yes, for executables # lib.a static archive # "both,no" lib.so.V(shr.o) shared, rtl:yes # lib.a(lib.so.V) shared, rtl:no, for executables # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a(lib.so.V) shared, rtl:no # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a static archive case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) for ld_flag in $LDFLAGS; do case $ld_flag in *-brtl*) aix_use_runtimelinking=yes break ;; esac done if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then # With aix-soname=svr4, we create the lib.so.V shared archives only, # so we don't have lib.a shared libs to link our executables. # We have to force runtime linking in this case. aix_use_runtimelinking=yes LDFLAGS="$LDFLAGS -Wl,-brtl" fi ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. archive_cmds_CXX='' hardcode_direct_CXX=yes hardcode_direct_absolute_CXX=yes hardcode_libdir_separator_CXX=':' link_all_deplibs_CXX=yes file_list_spec_CXX='$wl-f,' case $with_aix_soname,$aix_use_runtimelinking in aix,*) ;; # no import file svr4,* | *,yes) # use import file # The Import File defines what to hardcode. hardcode_direct_CXX=no hardcode_direct_absolute_CXX=no ;; esac if test yes = "$GXX"; then case $host_os in aix4.[012]|aix4.[012].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`$CC -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 hardcode_direct_CXX=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking hardcode_minus_L_CXX=yes hardcode_libdir_flag_spec_CXX='-L$libdir' hardcode_libdir_separator_CXX= fi esac shared_flag='-shared' if test yes = "$aix_use_runtimelinking"; then shared_flag=$shared_flag' $wl-G' fi # Need to ensure runtime linking is disabled for the traditional # shared library, or the linker may eventually find shared libraries # /with/ Import File - we do not want to mix them. shared_flag_aix='-shared' shared_flag_svr4='-shared $wl-G' else # not using gcc if test ia64 = "$host_cpu"; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test yes = "$aix_use_runtimelinking"; then shared_flag='$wl-G' else shared_flag='$wl-bM:SRE' fi shared_flag_aix='$wl-bM:SRE' shared_flag_svr4='$wl-G' fi fi export_dynamic_flag_spec_CXX='$wl-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to # export. always_export_symbols_CXX=yes if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. # The "-G" linker flag allows undefined symbols. no_undefined_flag_CXX='-bernotok' # Determine the default libpath from the value encoded in an empty # executable. if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else if test ${lt_cv_aix_libpath__CXX+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO" then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath__CXX"; then lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath__CXX"; then lt_cv_aix_libpath__CXX=/usr/lib:/lib fi fi aix_libpath=$lt_cv_aix_libpath__CXX fi hardcode_libdir_flag_spec_CXX='$wl-blibpath:$libdir:'"$aix_libpath" archive_expsym_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag else if test ia64 = "$host_cpu"; then hardcode_libdir_flag_spec_CXX='$wl-R $libdir:/usr/lib:/lib' allow_undefined_flag_CXX="-z nodefs" archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else if test ${lt_cv_aix_libpath__CXX+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO" then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath__CXX"; then lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath__CXX"; then lt_cv_aix_libpath__CXX=/usr/lib:/lib fi fi aix_libpath=$lt_cv_aix_libpath__CXX fi hardcode_libdir_flag_spec_CXX='$wl-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. no_undefined_flag_CXX=' $wl-bernotok' allow_undefined_flag_CXX=' $wl-berok' if test yes = "$with_gnu_ld"; then # We only use this code for GNU lds that support --whole-archive. whole_archive_flag_spec_CXX='$wl--whole-archive$convenience $wl--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives whole_archive_flag_spec_CXX='$convenience' fi archive_cmds_need_lc_CXX=yes archive_expsym_cmds_CXX='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' # -brtl affects multiple linker settings, -berok does not and is overridden later compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`' if test svr4 != "$with_aix_soname"; then # This is similar to how AIX traditionally builds its shared # libraries. Need -bnortl late, we may have -brtl in LDFLAGS. archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' fi if test aix != "$with_aix_soname"; then archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' else # used by -dlpreopen to get the symbols archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$MV $output_objdir/$realname.d/$soname $output_objdir' fi archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$RM -r $output_objdir/$realname.d' fi fi ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then allow_undefined_flag_CXX=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' else ld_shlibs_CXX=no fi ;; chorus*) case $cc_basename in *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; cygwin* | mingw* | pw32* | cegcc*) case $GXX,$cc_basename in ,cl* | no,cl* | ,icl* | no,icl*) # Native MSVC or ICC # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. hardcode_libdir_flag_spec_CXX=' ' allow_undefined_flag_CXX=unsupported always_export_symbols_CXX=yes file_list_spec_CXX='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. archive_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' archive_expsym_cmds_CXX='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then cp "$export_symbols" "$output_objdir/$soname.def"; echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; else $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, CXX)='true' enable_shared_with_static_runtimes_CXX=yes # Don't use ranlib old_postinstall_cmds_CXX='chmod 644 $oldlib' postlink_cmds_CXX='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile=$lt_outputfile.exe lt_tool_outputfile=$lt_tool_outputfile.exe ;; esac~ func_to_tool_file "$lt_outputfile"~ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # g++ # _LT_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless, # as there is no search path for DLLs. hardcode_libdir_flag_spec_CXX='-L$libdir' export_dynamic_flag_spec_CXX='$wl--export-all-symbols' allow_undefined_flag_CXX=unsupported always_export_symbols_CXX=no enable_shared_with_static_runtimes_CXX=yes if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file, use it as # is; otherwise, prepend EXPORTS... archive_expsym_cmds_CXX='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else ld_shlibs_CXX=no fi ;; esac ;; darwin* | rhapsody*) archive_cmds_need_lc_CXX=no hardcode_direct_CXX=no hardcode_automatic_CXX=yes hardcode_shlibpath_var_CXX=unsupported if test yes = "$lt_cv_ld_force_load"; then whole_archive_flag_spec_CXX='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' else whole_archive_flag_spec_CXX='' fi link_all_deplibs_CXX=yes allow_undefined_flag_CXX=$_lt_dar_allow_undefined case $cc_basename in ifort*|nagfor*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test yes = "$_lt_dar_can_shared"; then output_verbose_link_cmd=func_echo_all archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" archive_expsym_cmds_CXX="$SED 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" module_expsym_cmds_CXX="$SED -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" if test yes != "$lt_cv_apple_cc_single_mod"; then archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil" archive_expsym_cmds_CXX="$SED 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil" fi else ld_shlibs_CXX=no fi ;; os2*) hardcode_libdir_flag_spec_CXX='-L$libdir' hardcode_minus_L_CXX=yes allow_undefined_flag_CXX=unsupported shrext_cmds=.dll archive_cmds_CXX='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' archive_expsym_cmds_CXX='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' old_archive_From_new_cmds_CXX='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' enable_shared_with_static_runtimes_CXX=yes file_list_spec_CXX='@' ;; dgux*) case $cc_basename in ec++*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; ghcx*) # Green Hills C++ Compiler # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; freebsd2.*) # C++ shared libraries reported to be fairly broken before # switch to ELF ld_shlibs_CXX=no ;; freebsd-elf*) archive_cmds_need_lc_CXX=no ;; freebsd* | dragonfly* | midnightbsd*) # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF # conventions ld_shlibs_CXX=yes ;; haiku*) archive_cmds_CXX='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' link_all_deplibs_CXX=yes ;; hpux9*) hardcode_libdir_flag_spec_CXX='$wl+b $wl$libdir' hardcode_libdir_separator_CXX=: export_dynamic_flag_spec_CXX='$wl-E' hardcode_direct_CXX=yes hardcode_minus_L_CXX=yes # Not in the search PATH, # but as the default # location of the library. case $cc_basename in CC*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; aCC*) archive_cmds_CXX='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes = "$GXX"; then archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else # FIXME: insert proper C++ library support ld_shlibs_CXX=no fi ;; esac ;; hpux10*|hpux11*) if test no = "$with_gnu_ld"; then hardcode_libdir_flag_spec_CXX='$wl+b $wl$libdir' hardcode_libdir_separator_CXX=: case $host_cpu in hppa*64*|ia64*) ;; *) export_dynamic_flag_spec_CXX='$wl-E' ;; esac fi case $host_cpu in hppa*64*|ia64*) hardcode_direct_CXX=no hardcode_shlibpath_var_CXX=no ;; *) hardcode_direct_CXX=yes hardcode_direct_absolute_CXX=yes hardcode_minus_L_CXX=yes # Not in the search PATH, # but as the default # location of the library. ;; esac case $cc_basename in CC*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; aCC*) case $host_cpu in hppa*64*) archive_cmds_CXX='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) archive_cmds_CXX='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) archive_cmds_CXX='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes = "$GXX"; then if test no = "$with_gnu_ld"; then case $host_cpu in hppa*64*) archive_cmds_CXX='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) archive_cmds_CXX='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) archive_cmds_CXX='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac fi else # FIXME: insert proper C++ library support ld_shlibs_CXX=no fi ;; esac ;; interix[3-9]*) hardcode_direct_CXX=no hardcode_shlibpath_var_CXX=no hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' export_dynamic_flag_spec_CXX='$wl-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' archive_expsym_cmds_CXX='$SED "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; irix5* | irix6*) case $cc_basename in CC*) # SGI C++ archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' # Archives containing C++ object files must be created using # "CC -ar", where "CC" is the IRIX C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs' ;; *) if test yes = "$GXX"; then if test no = "$with_gnu_ld"; then archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' else archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib' fi fi link_all_deplibs_CXX=yes ;; esac hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' hardcode_libdir_separator_CXX=: inherit_rpath_CXX=yes ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' export_dynamic_flag_spec_CXX='$wl--export-dynamic' # Archives containing C++ object files must be created using # "CC -Bstatic", where "CC" is the KAI C++ compiler. old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;; icpc* | ecpc* ) # Intel C++ with_gnu_ld=yes # version 8.0 and above of icpc choke on multiply defined symbols # if we add $predep_objects and $postdep_objects, however 7.1 and # earlier do not add the objects themselves. case `$CC -V 2>&1` in *"Version 7."*) archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 8.0 or newer tmp_idyn= case $host_cpu in ia64*) tmp_idyn=' -i_dynamic';; esac archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; esac archive_cmds_need_lc_CXX=no hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' export_dynamic_flag_spec_CXX='$wl--export-dynamic' whole_archive_flag_spec_CXX='$wl--whole-archive$convenience $wl--no-whole-archive' ;; pgCC* | pgcpp*) # Portland Group C++ compiler case `$CC -V` in *pgCC\ [1-5].* | *pgcpp\ [1-5].*) prelink_cmds_CXX='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' old_archive_cmds_CXX='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ $RANLIB $oldlib' archive_cmds_CXX='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 6 and above use weak symbols archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; esac hardcode_libdir_flag_spec_CXX='$wl--rpath $wl$libdir' export_dynamic_flag_spec_CXX='$wl--export-dynamic' whole_archive_flag_spec_CXX='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' ;; cxx*) # Compaq C++ archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib $wl-retain-symbols-file $wl$export_symbols' runpath_var=LD_RUN_PATH hardcode_libdir_flag_spec_CXX='-rpath $libdir' hardcode_libdir_separator_CXX=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' ;; xl* | mpixl* | bgxl*) # IBM XL 8.0 on PPC, with GNU ld hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' export_dynamic_flag_spec_CXX='$wl--export-dynamic' archive_cmds_CXX='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' if test yes = "$supports_anon_versioning"; then archive_expsym_cmds_CXX='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi ;; *) case `$CC -V 2>&1 | $SED 5q` in *Sun\ C*) # Sun C++ 5.9 no_undefined_flag_CXX=' -zdefs' archive_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' archive_expsym_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols' hardcode_libdir_flag_spec_CXX='-R$libdir' whole_archive_flag_spec_CXX='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' compiler_needs_object_CXX=yes # Not sure whether something based on # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 # would be better. output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' ;; esac ;; esac ;; lynxos*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; m88k*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; mvs*) case $cc_basename in cxx*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds_CXX='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' wlarc= hardcode_libdir_flag_spec_CXX='-R$libdir' hardcode_direct_CXX=yes hardcode_shlibpath_var_CXX=no fi # Workaround some broken pre-1.5 toolchains output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' ;; *nto* | *qnx*) ld_shlibs_CXX=yes ;; openbsd* | bitrig*) if test -f /usr/libexec/ld.so; then hardcode_direct_CXX=yes hardcode_shlibpath_var_CXX=no hardcode_direct_absolute_CXX=yes archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib' export_dynamic_flag_spec_CXX='$wl-E' whole_archive_flag_spec_CXX=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' fi output_verbose_link_cmd=func_echo_all else ld_shlibs_CXX=no fi ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' hardcode_libdir_separator_CXX=: # Archives containing C++ object files must be created using # the KAI C++ compiler. case $host in osf3*) old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;; *) old_archive_cmds_CXX='$CC -o $oldlib $oldobjs' ;; esac ;; RCC*) # Rational C++ 2.4.1 # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; cxx*) case $host in osf3*) allow_undefined_flag_CXX=' $wl-expect_unresolved $wl\*' archive_cmds_CXX='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' ;; *) allow_undefined_flag_CXX=' -expect_unresolved \*' archive_cmds_CXX='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ echo "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~ $RM $lib.exp' hardcode_libdir_flag_spec_CXX='-rpath $libdir' ;; esac hardcode_libdir_separator_CXX=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes,no = "$GXX,$with_gnu_ld"; then allow_undefined_flag_CXX=' $wl-expect_unresolved $wl\*' case $host in osf3*) archive_cmds_CXX='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' ;; *) archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' ;; esac hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' hardcode_libdir_separator_CXX=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' else # FIXME: insert proper C++ library support ld_shlibs_CXX=no fi ;; esac ;; psos*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; lcc*) # Lucid # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ archive_cmds_need_lc_CXX=yes no_undefined_flag_CXX=' -zdefs' archive_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' hardcode_libdir_flag_spec_CXX='-R$libdir' hardcode_shlibpath_var_CXX=no case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands '-z linker_flag'. # Supported since Solaris 2.6 (maybe 2.5.1?) whole_archive_flag_spec_CXX='-z allextract$convenience -z defaultextract' ;; esac link_all_deplibs_CXX=yes output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' ;; gcx*) # Green Hills C++ Compiler archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' # The C++ compiler must be used to create the archive. old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs' ;; *) # GNU C++ compiler with Solaris linker if test yes,no = "$GXX,$with_gnu_ld"; then no_undefined_flag_CXX=' $wl-z ${wl}defs' if $CC --version | $GREP -v '^2\.7' > /dev/null; then archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' else # g++ 2.7 appears to require '-G' NOT '-shared' on this # platform. archive_cmds_CXX='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' fi hardcode_libdir_flag_spec_CXX='$wl-R $wl$libdir' case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) whole_archive_flag_spec_CXX='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' ;; esac fi ;; esac ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) no_undefined_flag_CXX='$wl-z,text' archive_cmds_need_lc_CXX=no hardcode_shlibpath_var_CXX=no runpath_var='LD_RUN_PATH' case $cc_basename in CC*) archive_cmds_CXX='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_CXX='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; *) archive_cmds_CXX='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_CXX='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We CANNOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. no_undefined_flag_CXX='$wl-z,text' allow_undefined_flag_CXX='$wl-z,nodefs' archive_cmds_need_lc_CXX=no hardcode_shlibpath_var_CXX=no hardcode_libdir_flag_spec_CXX='$wl-R,$libdir' hardcode_libdir_separator_CXX=':' link_all_deplibs_CXX=yes export_dynamic_flag_spec_CXX='$wl-Bexport' runpath_var='LD_RUN_PATH' case $cc_basename in CC*) archive_cmds_CXX='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_CXX='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' old_archive_cmds_CXX='$CC -Tprelink_objects $oldobjs~ '"$old_archive_cmds_CXX" reload_cmds_CXX='$CC -Tprelink_objects $reload_objs~ '"$reload_cmds_CXX" ;; *) archive_cmds_CXX='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_CXX='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; vxworks*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 printf "%s\n" "$ld_shlibs_CXX" >&6; } test no = "$ld_shlibs_CXX" && can_build_shared=no GCC_CXX=$GXX LD_CXX=$LD ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... # Dependencies to place before and after the object being linked: predep_objects_CXX= postdep_objects_CXX= predeps_CXX= postdeps_CXX= compiler_lib_search_path_CXX= cat > conftest.$ac_ext <<_LT_EOF class Foo { public: Foo (void) { a = 0; } private: int a; }; _LT_EOF _lt_libdeps_save_CFLAGS=$CFLAGS case "$CC $CFLAGS " in #( *\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; *\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; *\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; esac if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then # Parse the compiler output and extract the necessary # objects, libraries and library flags. # Sentinel used to keep track of whether or not we are before # the conftest object file. pre_test_object_deps_done=no for p in `eval "$output_verbose_link_cmd"`; do case $prev$p in -L* | -R* | -l*) # Some compilers place space between "-{L,R}" and the path. # Remove the space. if test x-L = "$p" || test x-R = "$p"; then prev=$p continue fi # Expand the sysroot to ease extracting the directories later. if test -z "$prev"; then case $p in -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; esac fi case $p in =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; esac if test no = "$pre_test_object_deps_done"; then case $prev in -L | -R) # Internal compiler library paths should come after those # provided the user. The postdeps already come after the # user supplied libs so there is no need to process them. if test -z "$compiler_lib_search_path_CXX"; then compiler_lib_search_path_CXX=$prev$p else compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} $prev$p" fi ;; # The "-l" case would never come before the object being # linked, so don't bother handling this case. esac else if test -z "$postdeps_CXX"; then postdeps_CXX=$prev$p else postdeps_CXX="${postdeps_CXX} $prev$p" fi fi prev= ;; *.lto.$objext) ;; # Ignore GCC LTO objects *.$objext) # This assumes that the test object file only shows up # once in the compiler output. if test "$p" = "conftest.$objext"; then pre_test_object_deps_done=yes continue fi if test no = "$pre_test_object_deps_done"; then if test -z "$predep_objects_CXX"; then predep_objects_CXX=$p else predep_objects_CXX="$predep_objects_CXX $p" fi else if test -z "$postdep_objects_CXX"; then postdep_objects_CXX=$p else postdep_objects_CXX="$postdep_objects_CXX $p" fi fi ;; *) ;; # Ignore the rest. esac done # Clean up. rm -f a.out a.exe else echo "libtool.m4: error: problem compiling CXX test program" fi $RM -f confest.$objext CFLAGS=$_lt_libdeps_save_CFLAGS # PORTME: override above test on systems where it is broken case $host_os in interix[3-9]*) # Interix 3.5 installs completely hosed .la files for C++, so rather than # hack all around it, let's just trust "g++" to DTRT. predep_objects_CXX= postdep_objects_CXX= postdeps_CXX= ;; esac case " $postdeps_CXX " in *" -lc "*) archive_cmds_need_lc_CXX=no ;; esac compiler_lib_search_dirs_CXX= if test -n "${compiler_lib_search_path_CXX}"; then compiler_lib_search_dirs_CXX=`echo " ${compiler_lib_search_path_CXX}" | $SED -e 's! -L! !g' -e 's!^ !!'` fi lt_prog_compiler_wl_CXX= lt_prog_compiler_pic_CXX= lt_prog_compiler_static_CXX= # C++ specific cases for pic, static, wl, etc. if test yes = "$GXX"; then lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_static_CXX='-static' case $host_os in aix*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor lt_prog_compiler_static_CXX='-Bstatic' fi lt_prog_compiler_pic_CXX='-fPIC' ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support lt_prog_compiler_pic_CXX='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the '-m68020' flag to GCC prevents building anything better, # like '-m68040'. lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries lt_prog_compiler_pic_CXX='-DDLL_EXPORT' case $host_os in os2*) lt_prog_compiler_static_CXX='$wl-static' ;; esac ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic_CXX='-fno-common' ;; *djgpp*) # DJGPP does not support shared libraries at all lt_prog_compiler_pic_CXX= ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. lt_prog_compiler_static_CXX= ;; interix[3-9]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic_CXX=-Kconform_pic fi ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) ;; *) lt_prog_compiler_pic_CXX='-fPIC' ;; esac ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic_CXX='-fPIC -shared' ;; *) lt_prog_compiler_pic_CXX='-fPIC' ;; esac else case $host_os in aix[4-9]*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor lt_prog_compiler_static_CXX='-Bstatic' else lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp' fi ;; chorus*) case $cc_basename in cxch68*) # Green Hills C++ Compiler # _LT_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" ;; esac ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). lt_prog_compiler_pic_CXX='-DDLL_EXPORT' ;; dgux*) case $cc_basename in ec++*) lt_prog_compiler_pic_CXX='-KPIC' ;; ghcx*) # Green Hills C++ Compiler lt_prog_compiler_pic_CXX='-pic' ;; *) ;; esac ;; freebsd* | dragonfly* | midnightbsd*) # FreeBSD uses GNU C++ ;; hpux9* | hpux10* | hpux11*) case $cc_basename in CC*) lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_static_CXX='$wl-a ${wl}archive' if test ia64 != "$host_cpu"; then lt_prog_compiler_pic_CXX='+Z' fi ;; aCC*) lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_static_CXX='$wl-a ${wl}archive' case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) lt_prog_compiler_pic_CXX='+Z' ;; esac ;; *) ;; esac ;; interix*) # This is c89, which is MS Visual C++ (no shared libs) # Anyone wants to do a port? ;; irix5* | irix6* | nonstopux*) case $cc_basename in CC*) lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_static_CXX='-non_shared' # CC pic flag -KPIC is the default. ;; *) ;; esac ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # KAI C++ Compiler lt_prog_compiler_wl_CXX='--backend -Wl,' lt_prog_compiler_pic_CXX='-fPIC' ;; ecpc* ) # old Intel C++ for x86_64, which still supported -KPIC. lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-KPIC' lt_prog_compiler_static_CXX='-static' ;; icpc* ) # Intel C++, used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-fPIC' lt_prog_compiler_static_CXX='-static' ;; pgCC* | pgcpp*) # Portland Group C++ compiler lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-fpic' lt_prog_compiler_static_CXX='-Bstatic' ;; cxx*) # Compaq C++ # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. lt_prog_compiler_pic_CXX= lt_prog_compiler_static_CXX='-non_shared' ;; xlc* | xlC* | bgxl[cC]* | mpixl[cC]*) # IBM XL 8.0, 9.0 on PPC and BlueGene lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-qpic' lt_prog_compiler_static_CXX='-qstaticlink' ;; *) case `$CC -V 2>&1 | $SED 5q` in *Sun\ C*) # Sun C++ 5.9 lt_prog_compiler_pic_CXX='-KPIC' lt_prog_compiler_static_CXX='-Bstatic' lt_prog_compiler_wl_CXX='-Qoption ld ' ;; esac ;; esac ;; lynxos*) ;; m88k*) ;; mvs*) case $cc_basename in cxx*) lt_prog_compiler_pic_CXX='-W c,exportall' ;; *) ;; esac ;; netbsd* | netbsdelf*-gnu) ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic_CXX='-fPIC -shared' ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) lt_prog_compiler_wl_CXX='--backend -Wl,' ;; RCC*) # Rational C++ 2.4.1 lt_prog_compiler_pic_CXX='-pic' ;; cxx*) # Digital/Compaq C++ lt_prog_compiler_wl_CXX='-Wl,' # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. lt_prog_compiler_pic_CXX= lt_prog_compiler_static_CXX='-non_shared' ;; *) ;; esac ;; psos*) ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ lt_prog_compiler_pic_CXX='-KPIC' lt_prog_compiler_static_CXX='-Bstatic' lt_prog_compiler_wl_CXX='-Qoption ld ' ;; gcx*) # Green Hills C++ Compiler lt_prog_compiler_pic_CXX='-PIC' ;; *) ;; esac ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x lt_prog_compiler_pic_CXX='-pic' lt_prog_compiler_static_CXX='-Bstatic' ;; lcc*) # Lucid lt_prog_compiler_pic_CXX='-pic' ;; *) ;; esac ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) case $cc_basename in CC*) lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-KPIC' lt_prog_compiler_static_CXX='-Bstatic' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 lt_prog_compiler_pic_CXX='-KPIC' ;; *) ;; esac ;; vxworks*) ;; *) lt_prog_compiler_can_build_shared_CXX=no ;; esac fi case $host_os in # For platforms that do not support PIC, -DPIC is meaningless: *djgpp*) lt_prog_compiler_pic_CXX= ;; *) lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC" ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 printf %s "checking for $compiler option to produce PIC... " >&6; } if test ${lt_cv_prog_compiler_pic_CXX+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_prog_compiler_pic_CXX=$lt_prog_compiler_pic_CXX fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_CXX" >&5 printf "%s\n" "$lt_cv_prog_compiler_pic_CXX" >&6; } lt_prog_compiler_pic_CXX=$lt_cv_prog_compiler_pic_CXX # # Check to make sure the PIC flag actually works. # if test -n "$lt_prog_compiler_pic_CXX"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5 printf %s "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... " >&6; } if test ${lt_cv_prog_compiler_pic_works_CXX+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_prog_compiler_pic_works_CXX=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC" ## exclude from sc_useless_quotes_in_assignment # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_pic_works_CXX=yes fi fi $RM conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_CXX" >&5 printf "%s\n" "$lt_cv_prog_compiler_pic_works_CXX" >&6; } if test yes = "$lt_cv_prog_compiler_pic_works_CXX"; then case $lt_prog_compiler_pic_CXX in "" | " "*) ;; *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;; esac else lt_prog_compiler_pic_CXX= lt_prog_compiler_can_build_shared_CXX=no fi fi # # Check to make sure the static flag actually works. # wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 printf %s "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } if test ${lt_cv_prog_compiler_static_works_CXX+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_prog_compiler_static_works_CXX=no save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS $lt_tmp_static_flag" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_static_works_CXX=yes fi else lt_cv_prog_compiler_static_works_CXX=yes fi fi $RM -r conftest* LDFLAGS=$save_LDFLAGS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_CXX" >&5 printf "%s\n" "$lt_cv_prog_compiler_static_works_CXX" >&6; } if test yes = "$lt_cv_prog_compiler_static_works_CXX"; then : else lt_prog_compiler_static_CXX= fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 printf %s "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if test ${lt_cv_prog_compiler_c_o_CXX+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_prog_compiler_c_o_CXX=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o_CXX=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 printf "%s\n" "$lt_cv_prog_compiler_c_o_CXX" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 printf %s "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if test ${lt_cv_prog_compiler_c_o_CXX+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_prog_compiler_c_o_CXX=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o_CXX=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 printf "%s\n" "$lt_cv_prog_compiler_c_o_CXX" >&6; } hard_links=nottested if test no = "$lt_cv_prog_compiler_c_o_CXX" && test no != "$need_locks"; then # do not overwrite the value of need_locks provided by the user { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 printf %s "checking if we can lock with hard links... " >&6; } hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 printf "%s\n" "$hard_links" >&6; } if test no = "$hard_links"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5 printf "%s\n" "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;} need_locks=warn fi else need_locks=no fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 printf %s "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' case $host_os in aix[4-9]*) # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to GNU nm, but means don't demangle to AIX nm. # Without the "-l" option, or with the "-B" option, AIX nm treats # weak defined symbols like other global defined symbols, whereas # GNU nm marks them as "W". # While the 'weak' keyword is ignored in the Export File, we need # it in the Import File for the 'aix-soname' feature, so we have # to replace the "-B" option with "-P" for AIX nm. if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else export_symbols_cmds_CXX='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' fi ;; pw32*) export_symbols_cmds_CXX=$ltdll_cmds ;; cygwin* | mingw* | cegcc*) case $cc_basename in cl* | icl*) exclude_expsyms_CXX='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' ;; *) export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' exclude_expsyms_CXX='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' ;; esac ;; linux* | k*bsd*-gnu | gnu*) link_all_deplibs_CXX=no ;; *) export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 printf "%s\n" "$ld_shlibs_CXX" >&6; } test no = "$ld_shlibs_CXX" && can_build_shared=no with_gnu_ld_CXX=$with_gnu_ld # # Do we need to explicitly link libc? # case "x$archive_cmds_need_lc_CXX" in x|xyes) # Assume -lc should be added archive_cmds_need_lc_CXX=yes if test yes,yes = "$GCC,$enable_shared"; then case $archive_cmds_CXX in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 printf %s "checking whether -lc should be explicitly linked in... " >&6; } if test ${lt_cv_archive_cmds_need_lc_CXX+y} then : printf %s "(cached) " >&6 else $as_nop $RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$lt_prog_compiler_wl_CXX pic_flag=$lt_prog_compiler_pic_CXX compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$allow_undefined_flag_CXX allow_undefined_flag_CXX= if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 (eval $archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then lt_cv_archive_cmds_need_lc_CXX=no else lt_cv_archive_cmds_need_lc_CXX=yes fi allow_undefined_flag_CXX=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc_CXX" >&5 printf "%s\n" "$lt_cv_archive_cmds_need_lc_CXX" >&6; } archive_cmds_need_lc_CXX=$lt_cv_archive_cmds_need_lc_CXX ;; esac fi ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 printf %s "checking dynamic linker characteristics... " >&6; } library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=.so postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='$libname$release$shared_ext$major' ;; aix[4-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes if test ia64 = "$host_cpu"; then # AIX 5 supports IA64 library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line '#! .'. This would cause the generated library to # depend on '.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[01] | aix4.[01].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # Using Import Files as archive members, it is possible to support # filename-based versioning of shared library archives on AIX. While # this would work for both with and without runtime linking, it will # prevent static linking of such archives. So we do filename-based # shared library versioning with .so extension only, which is used # when both runtime linking and shared linking is enabled. # Unfortunately, runtime linking may impact performance, so we do # not want this to be the default eventually. Also, we use the # versioned .so libs for executables only if there is the -brtl # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. # To allow for filename-based versioning support, we need to create # libNAME.so.V as an archive file, containing: # *) an Import File, referring to the versioned filename of the # archive as well as the shared archive member, telling the # bitwidth (32 or 64) of that shared object, and providing the # list of exported symbols of that shared object, eventually # decorated with the 'weak' keyword # *) the shared object with the F_LOADONLY flag set, to really avoid # it being seen by the linker. # At run time we better use the real file rather than another symlink, # but for link time we create the symlink libNAME.so -> libNAME.so.V case $with_aix_soname,$aix_use_runtimelinking in # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. aix,yes) # traditional libtool dynamic_linker='AIX unversionable lib.so' # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; aix,no) # traditional AIX only dynamic_linker='AIX lib.a(lib.so.V)' # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' ;; svr4,*) # full svr4 only dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,yes) # both, prefer svr4 dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # unpreferred sharedlib libNAME.a needs extra handling postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,no) # both, prefer aix dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)" library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' ;; esac shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='$libname$shared_ext' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[45]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no case $GCC,$cc_basename in yes,*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo $libname | $SED -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo $libname | $SED -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' ;; esac dynamic_linker='Win32 ld.exe' ;; *,cl* | *,icl*) # Native MSVC or ICC libname_spec='$name' soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' library_names_spec='$libname.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec=$LIB if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC and ICC wrapper library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' soname_spec='$libname$release$major$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd* | dragonfly* | midnightbsd*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[23].*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2.*) shlibpath_overrides_runpath=yes ;; freebsd3.[01]* | freebsdelf3.[01]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=no sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' if test 32 = "$HPUX_IA64_MODE"; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" sys_lib_dlsearch_path_spec=/usr/lib/hpux32 else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" sys_lib_dlsearch_path_spec=/usr/lib/hpux64 fi ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... postinstall_cmds='chmod 555 $lib' # or fails outright, so override atomically: install_override_mode=555 ;; interix[3-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test yes = "$lt_cv_prog_gnu_ld"; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; linux*android*) version_type=none # Android doesn't support versioned libraries. need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext' soname_spec='$libname$release$shared_ext' finish_cmds= shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes dynamic_linker='Android linker' # Don't embed -rpath directories since the linker doesn't support them. hardcode_libdir_flag_spec_CXX='-L$libdir' ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH if test ${lt_cv_shlibpath_overrides_runpath+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$lt_prog_compiler_wl_CXX\"; \ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec_CXX\"" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO" then : if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null then : lt_cv_shlibpath_overrides_runpath=yes fi fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS libdir=$save_libdir fi shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Ideally, we could use ldconfig to report *all* directores which are # searched for libraries, however this is still not possible. Aside from not # being certain /sbin/ldconfig is available, command # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, # even though it is searched at run-time. Try to do the best guess by # appending ld.so.conf contents (and includes) to the search path. if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsdelf*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='NetBSD ld.elf_so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd* | bitrig*) version_type=sunos sys_lib_dlsearch_path_spec=/usr/lib need_lib_prefix=no if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then need_version=no else need_version=yes fi library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; os2*) libname_spec='$name' version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no # OS/2 can only load a DLL with a base name of 8 characters or less. soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; v=$($ECHO $release$versuffix | tr -d .-); n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); $ECHO $n$v`$shared_ext' library_names_spec='${libname}_dll.$libext' dynamic_linker='OS/2 ld.exe' shlibpath_var=BEGINLIBPATH sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test yes = "$with_gnu_ld"; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec; then version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' soname_spec='$libname$shared_ext.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=sco need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test yes = "$with_gnu_ld"; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 printf "%s\n" "$dynamic_linker" >&6; } test no = "$dynamic_linker" && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test yes = "$GCC"; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec fi if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec fi # remember unaugmented sys_lib_dlsearch_path content for libtool script decls... configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec # ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" # to be used as default LT_SYS_LIBRARY_PATH value in generated libtool configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 printf %s "checking how to hardcode library paths into programs... " >&6; } hardcode_action_CXX= if test -n "$hardcode_libdir_flag_spec_CXX" || test -n "$runpath_var_CXX" || test yes = "$hardcode_automatic_CXX"; then # We can hardcode non-existent directories. if test no != "$hardcode_direct_CXX" && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, CXX)" && test no != "$hardcode_minus_L_CXX"; then # Linking always hardcodes the temporary library directory. hardcode_action_CXX=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. hardcode_action_CXX=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. hardcode_action_CXX=unsupported fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $hardcode_action_CXX" >&5 printf "%s\n" "$hardcode_action_CXX" >&6; } if test relink = "$hardcode_action_CXX" || test yes = "$inherit_rpath_CXX"; then # Fast installation is not supported enable_fast_install=no elif test yes = "$shlibpath_overrides_runpath" || test no = "$enable_shared"; then # Fast installation is not necessary enable_fast_install=needless fi fi # test -n "$compiler" CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS LDCXX=$LD LD=$lt_save_LD GCC=$lt_save_GCC with_gnu_ld=$lt_save_with_gnu_ld lt_cv_path_LDCXX=$lt_cv_path_LD lt_cv_path_LD=$lt_save_path_LD lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld fi # test yes != "$_lt_caught_CXX_error" ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C++ compiler works" >&5 printf %s "checking whether the C++ compiler works... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ class Test {public: static int main() {return 0;}}; int main (void) { Test::main(); ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } as_fn_error $? "The C++ compiler $CXX does not work. Please install a working C++ compiler or define CXX to the appropriate value." "$LINENO" 5 fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ax_cxx_compile_alternatives="17 1z" ax_cxx_compile_cxx17_required=true ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ac_success=no { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++17 features by default" >&5 printf %s "checking whether $CXX supports C++17 features by default... " >&6; } if test ${ax_cv_cxx_compile_cxx17+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ // If the compiler admits that it is not ready for C++11, why torture it? // Hopefully, this will speed up the test. #ifndef __cplusplus #error "This is not a C++ compiler" #elif __cplusplus < 201103L #error "This is not a C++11 compiler" #else namespace cxx11 { namespace test_static_assert { template struct check { static_assert(sizeof(int) <= sizeof(T), "not big enough"); }; } namespace test_final_override { struct Base { virtual ~Base() {} virtual void f() {} }; struct Derived : public Base { virtual ~Derived() override {} virtual void f() override {} }; } namespace test_double_right_angle_brackets { template < typename T > struct check {}; typedef check single_type; typedef check> double_type; typedef check>> triple_type; typedef check>>> quadruple_type; } namespace test_decltype { int f() { int a = 1; decltype(a) b = 2; return a + b; } } namespace test_type_deduction { template < typename T1, typename T2 > struct is_same { static const bool value = false; }; template < typename T > struct is_same { static const bool value = true; }; template < typename T1, typename T2 > auto add(T1 a1, T2 a2) -> decltype(a1 + a2) { return a1 + a2; } int test(const int c, volatile int v) { static_assert(is_same::value == true, ""); static_assert(is_same::value == false, ""); static_assert(is_same::value == false, ""); auto ac = c; auto av = v; auto sumi = ac + av + 'x'; auto sumf = ac + av + 1.0; static_assert(is_same::value == true, ""); static_assert(is_same::value == true, ""); static_assert(is_same::value == true, ""); static_assert(is_same::value == false, ""); static_assert(is_same::value == true, ""); return (sumf > 0.0) ? sumi : add(c, v); } } namespace test_noexcept { int f() { return 0; } int g() noexcept { return 0; } static_assert(noexcept(f()) == false, ""); static_assert(noexcept(g()) == true, ""); } namespace test_constexpr { template < typename CharT > unsigned long constexpr strlen_c_r(const CharT *const s, const unsigned long acc) noexcept { return *s ? strlen_c_r(s + 1, acc + 1) : acc; } template < typename CharT > unsigned long constexpr strlen_c(const CharT *const s) noexcept { return strlen_c_r(s, 0UL); } static_assert(strlen_c("") == 0UL, ""); static_assert(strlen_c("1") == 1UL, ""); static_assert(strlen_c("example") == 7UL, ""); static_assert(strlen_c("another\0example") == 7UL, ""); } namespace test_rvalue_references { template < int N > struct answer { static constexpr int value = N; }; answer<1> f(int&) { return answer<1>(); } answer<2> f(const int&) { return answer<2>(); } answer<3> f(int&&) { return answer<3>(); } void test() { int i = 0; const int c = 0; static_assert(decltype(f(i))::value == 1, ""); static_assert(decltype(f(c))::value == 2, ""); static_assert(decltype(f(0))::value == 3, ""); } } namespace test_uniform_initialization { struct test { static const int zero {}; static const int one {1}; }; static_assert(test::zero == 0, ""); static_assert(test::one == 1, ""); } namespace test_lambdas { void test1() { auto lambda1 = [](){}; auto lambda2 = lambda1; lambda1(); lambda2(); } int test2() { auto a = [](int i, int j){ return i + j; }(1, 2); auto b = []() -> int { return '0'; }(); auto c = [=](){ return a + b; }(); auto d = [&](){ return c; }(); auto e = [a, &b](int x) mutable { const auto identity = [](int y){ return y; }; for (auto i = 0; i < a; ++i) a += b--; return x + identity(a + b); }(0); return a + b + c + d + e; } int test3() { const auto nullary = [](){ return 0; }; const auto unary = [](int x){ return x; }; using nullary_t = decltype(nullary); using unary_t = decltype(unary); const auto higher1st = [](nullary_t f){ return f(); }; const auto higher2nd = [unary](nullary_t f1){ return [unary, f1](unary_t f2){ return f2(unary(f1())); }; }; return higher1st(nullary) + higher2nd(nullary)(unary); } } namespace test_variadic_templates { template struct sum; template struct sum { static constexpr auto value = N0 + sum::value; }; template <> struct sum<> { static constexpr auto value = 0; }; static_assert(sum<>::value == 0, ""); static_assert(sum<1>::value == 1, ""); static_assert(sum<23>::value == 23, ""); static_assert(sum<1, 2>::value == 3, ""); static_assert(sum<5, 5, 11>::value == 21, ""); static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); } // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function // because of this. namespace test_template_alias_sfinae { struct foo {}; template using member = typename T::member_type; template void func(...) {} template void func(member*) {} void test(); void test() { func(0); } } } // namespace cxx11 #endif // __cplusplus >= 201103L // If the compiler admits that it is not ready for C++14, why torture it? // Hopefully, this will speed up the test. #ifndef __cplusplus #error "This is not a C++ compiler" #elif __cplusplus < 201402L #error "This is not a C++14 compiler" #else namespace cxx14 { namespace test_polymorphic_lambdas { int test() { const auto lambda = [](auto&&... args){ const auto istiny = [](auto x){ return (sizeof(x) == 1UL) ? 1 : 0; }; const int aretiny[] = { istiny(args)... }; return aretiny[0]; }; return lambda(1, 1L, 1.0f, '1'); } } namespace test_binary_literals { constexpr auto ivii = 0b0000000000101010; static_assert(ivii == 42, "wrong value"); } namespace test_generalized_constexpr { template < typename CharT > constexpr unsigned long strlen_c(const CharT *const s) noexcept { auto length = 0UL; for (auto p = s; *p; ++p) ++length; return length; } static_assert(strlen_c("") == 0UL, ""); static_assert(strlen_c("x") == 1UL, ""); static_assert(strlen_c("test") == 4UL, ""); static_assert(strlen_c("another\0test") == 7UL, ""); } namespace test_lambda_init_capture { int test() { auto x = 0; const auto lambda1 = [a = x](int b){ return a + b; }; const auto lambda2 = [a = lambda1(x)](){ return a; }; return lambda2(); } } namespace test_digit_separators { constexpr auto ten_million = 100'000'000; static_assert(ten_million == 100000000, ""); } namespace test_return_type_deduction { auto f(int& x) { return x; } decltype(auto) g(int& x) { return x; } template < typename T1, typename T2 > struct is_same { static constexpr auto value = false; }; template < typename T > struct is_same { static constexpr auto value = true; }; int test() { auto x = 0; static_assert(is_same::value, ""); static_assert(is_same::value, ""); return x; } } } // namespace cxx14 #endif // __cplusplus >= 201402L // If the compiler admits that it is not ready for C++17, why torture it? // Hopefully, this will speed up the test. #ifndef __cplusplus #error "This is not a C++ compiler" #elif __cplusplus < 201703L #error "This is not a C++17 compiler" #else #include #include #include namespace cxx17 { namespace test_constexpr_lambdas { constexpr int foo = [](){return 42;}(); } namespace test::nested_namespace::definitions { } namespace test_fold_expression { template int multiply(Args... args) { return (args * ... * 1); } template bool all(Args... args) { return (args && ...); } } namespace test_extended_static_assert { static_assert (true); } namespace test_auto_brace_init_list { auto foo = {5}; auto bar {5}; static_assert(std::is_same, decltype(foo)>::value); static_assert(std::is_same::value); } namespace test_typename_in_template_template_parameter { template typename X> struct D; } namespace test_fallthrough_nodiscard_maybe_unused_attributes { int f1() { return 42; } [[nodiscard]] int f2() { [[maybe_unused]] auto unused = f1(); switch (f1()) { case 17: f1(); [[fallthrough]]; case 42: f1(); } return f1(); } } namespace test_extended_aggregate_initialization { struct base1 { int b1, b2 = 42; }; struct base2 { base2() { b3 = 42; } int b3; }; struct derived : base1, base2 { int d; }; derived d1 {{1, 2}, {}, 4}; // full initialization derived d2 {{}, {}, 4}; // value-initialized bases } namespace test_general_range_based_for_loop { struct iter { int i; int& operator* () { return i; } const int& operator* () const { return i; } iter& operator++() { ++i; return *this; } }; struct sentinel { int i; }; bool operator== (const iter& i, const sentinel& s) { return i.i == s.i; } bool operator!= (const iter& i, const sentinel& s) { return !(i == s); } struct range { iter begin() const { return {0}; } sentinel end() const { return {5}; } }; void f() { range r {}; for (auto i : r) { [[maybe_unused]] auto v = i; } } } namespace test_lambda_capture_asterisk_this_by_value { struct t { int i; int foo() { return [*this]() { return i; }(); } }; } namespace test_enum_class_construction { enum class byte : unsigned char {}; byte foo {42}; } namespace test_constexpr_if { template int f () { if constexpr(cond) { return 13; } else { return 42; } } } namespace test_selection_statement_with_initializer { int f() { return 13; } int f2() { if (auto i = f(); i > 0) { return 3; } switch (auto i = f(); i + 4) { case 17: return 2; default: return 1; } } } namespace test_template_argument_deduction_for_class_templates { template struct pair { pair (T1 p1, T2 p2) : m1 {p1}, m2 {p2} {} T1 m1; T2 m2; }; void f() { [[maybe_unused]] auto p = pair{13, 42u}; } } namespace test_non_type_auto_template_parameters { template struct B {}; B<5> b1; B<'a'> b2; } namespace test_structured_bindings { int arr[2] = { 1, 2 }; std::pair pr = { 1, 2 }; auto f1() -> int(&)[2] { return arr; } auto f2() -> std::pair& { return pr; } struct S { int x1 : 2; volatile double y1; }; S f3() { return {}; } auto [ x1, y1 ] = f1(); auto& [ xr1, yr1 ] = f1(); auto [ x2, y2 ] = f2(); auto& [ xr2, yr2 ] = f2(); const auto [ x3, y3 ] = f3(); } namespace test_exception_spec_type_system { struct Good {}; struct Bad {}; void g1() noexcept; void g2(); template Bad f(T*, T*); template Good f(T1*, T2*); static_assert (std::is_same_v); } namespace test_inline_variables { template void f(T) {} template inline T g(T) { return T{}; } template<> inline void f<>(int) {} template<> int g<>(int) { return 5; } } } // namespace cxx17 #endif // __cplusplus < 201703L _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : ax_cv_cxx_compile_cxx17=yes else $as_nop ax_cv_cxx_compile_cxx17=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_cxx_compile_cxx17" >&5 printf "%s\n" "$ax_cv_cxx_compile_cxx17" >&6; } if test x$ax_cv_cxx_compile_cxx17 = xyes; then ac_success=yes fi if test x$ac_success = xno; then for alternative in ${ax_cxx_compile_alternatives}; do switch="-std=gnu++${alternative}" cachevar=`printf "%s\n" "ax_cv_cxx_compile_cxx17_$switch" | $as_tr_sh` { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++17 features with $switch" >&5 printf %s "checking whether $CXX supports C++17 features with $switch... " >&6; } if eval test \${$cachevar+y} then : printf %s "(cached) " >&6 else $as_nop ac_save_CXX="$CXX" CXX="$CXX $switch" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ // If the compiler admits that it is not ready for C++11, why torture it? // Hopefully, this will speed up the test. #ifndef __cplusplus #error "This is not a C++ compiler" #elif __cplusplus < 201103L #error "This is not a C++11 compiler" #else namespace cxx11 { namespace test_static_assert { template struct check { static_assert(sizeof(int) <= sizeof(T), "not big enough"); }; } namespace test_final_override { struct Base { virtual ~Base() {} virtual void f() {} }; struct Derived : public Base { virtual ~Derived() override {} virtual void f() override {} }; } namespace test_double_right_angle_brackets { template < typename T > struct check {}; typedef check single_type; typedef check> double_type; typedef check>> triple_type; typedef check>>> quadruple_type; } namespace test_decltype { int f() { int a = 1; decltype(a) b = 2; return a + b; } } namespace test_type_deduction { template < typename T1, typename T2 > struct is_same { static const bool value = false; }; template < typename T > struct is_same { static const bool value = true; }; template < typename T1, typename T2 > auto add(T1 a1, T2 a2) -> decltype(a1 + a2) { return a1 + a2; } int test(const int c, volatile int v) { static_assert(is_same::value == true, ""); static_assert(is_same::value == false, ""); static_assert(is_same::value == false, ""); auto ac = c; auto av = v; auto sumi = ac + av + 'x'; auto sumf = ac + av + 1.0; static_assert(is_same::value == true, ""); static_assert(is_same::value == true, ""); static_assert(is_same::value == true, ""); static_assert(is_same::value == false, ""); static_assert(is_same::value == true, ""); return (sumf > 0.0) ? sumi : add(c, v); } } namespace test_noexcept { int f() { return 0; } int g() noexcept { return 0; } static_assert(noexcept(f()) == false, ""); static_assert(noexcept(g()) == true, ""); } namespace test_constexpr { template < typename CharT > unsigned long constexpr strlen_c_r(const CharT *const s, const unsigned long acc) noexcept { return *s ? strlen_c_r(s + 1, acc + 1) : acc; } template < typename CharT > unsigned long constexpr strlen_c(const CharT *const s) noexcept { return strlen_c_r(s, 0UL); } static_assert(strlen_c("") == 0UL, ""); static_assert(strlen_c("1") == 1UL, ""); static_assert(strlen_c("example") == 7UL, ""); static_assert(strlen_c("another\0example") == 7UL, ""); } namespace test_rvalue_references { template < int N > struct answer { static constexpr int value = N; }; answer<1> f(int&) { return answer<1>(); } answer<2> f(const int&) { return answer<2>(); } answer<3> f(int&&) { return answer<3>(); } void test() { int i = 0; const int c = 0; static_assert(decltype(f(i))::value == 1, ""); static_assert(decltype(f(c))::value == 2, ""); static_assert(decltype(f(0))::value == 3, ""); } } namespace test_uniform_initialization { struct test { static const int zero {}; static const int one {1}; }; static_assert(test::zero == 0, ""); static_assert(test::one == 1, ""); } namespace test_lambdas { void test1() { auto lambda1 = [](){}; auto lambda2 = lambda1; lambda1(); lambda2(); } int test2() { auto a = [](int i, int j){ return i + j; }(1, 2); auto b = []() -> int { return '0'; }(); auto c = [=](){ return a + b; }(); auto d = [&](){ return c; }(); auto e = [a, &b](int x) mutable { const auto identity = [](int y){ return y; }; for (auto i = 0; i < a; ++i) a += b--; return x + identity(a + b); }(0); return a + b + c + d + e; } int test3() { const auto nullary = [](){ return 0; }; const auto unary = [](int x){ return x; }; using nullary_t = decltype(nullary); using unary_t = decltype(unary); const auto higher1st = [](nullary_t f){ return f(); }; const auto higher2nd = [unary](nullary_t f1){ return [unary, f1](unary_t f2){ return f2(unary(f1())); }; }; return higher1st(nullary) + higher2nd(nullary)(unary); } } namespace test_variadic_templates { template struct sum; template struct sum { static constexpr auto value = N0 + sum::value; }; template <> struct sum<> { static constexpr auto value = 0; }; static_assert(sum<>::value == 0, ""); static_assert(sum<1>::value == 1, ""); static_assert(sum<23>::value == 23, ""); static_assert(sum<1, 2>::value == 3, ""); static_assert(sum<5, 5, 11>::value == 21, ""); static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); } // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function // because of this. namespace test_template_alias_sfinae { struct foo {}; template using member = typename T::member_type; template void func(...) {} template void func(member*) {} void test(); void test() { func(0); } } } // namespace cxx11 #endif // __cplusplus >= 201103L // If the compiler admits that it is not ready for C++14, why torture it? // Hopefully, this will speed up the test. #ifndef __cplusplus #error "This is not a C++ compiler" #elif __cplusplus < 201402L #error "This is not a C++14 compiler" #else namespace cxx14 { namespace test_polymorphic_lambdas { int test() { const auto lambda = [](auto&&... args){ const auto istiny = [](auto x){ return (sizeof(x) == 1UL) ? 1 : 0; }; const int aretiny[] = { istiny(args)... }; return aretiny[0]; }; return lambda(1, 1L, 1.0f, '1'); } } namespace test_binary_literals { constexpr auto ivii = 0b0000000000101010; static_assert(ivii == 42, "wrong value"); } namespace test_generalized_constexpr { template < typename CharT > constexpr unsigned long strlen_c(const CharT *const s) noexcept { auto length = 0UL; for (auto p = s; *p; ++p) ++length; return length; } static_assert(strlen_c("") == 0UL, ""); static_assert(strlen_c("x") == 1UL, ""); static_assert(strlen_c("test") == 4UL, ""); static_assert(strlen_c("another\0test") == 7UL, ""); } namespace test_lambda_init_capture { int test() { auto x = 0; const auto lambda1 = [a = x](int b){ return a + b; }; const auto lambda2 = [a = lambda1(x)](){ return a; }; return lambda2(); } } namespace test_digit_separators { constexpr auto ten_million = 100'000'000; static_assert(ten_million == 100000000, ""); } namespace test_return_type_deduction { auto f(int& x) { return x; } decltype(auto) g(int& x) { return x; } template < typename T1, typename T2 > struct is_same { static constexpr auto value = false; }; template < typename T > struct is_same { static constexpr auto value = true; }; int test() { auto x = 0; static_assert(is_same::value, ""); static_assert(is_same::value, ""); return x; } } } // namespace cxx14 #endif // __cplusplus >= 201402L // If the compiler admits that it is not ready for C++17, why torture it? // Hopefully, this will speed up the test. #ifndef __cplusplus #error "This is not a C++ compiler" #elif __cplusplus < 201703L #error "This is not a C++17 compiler" #else #include #include #include namespace cxx17 { namespace test_constexpr_lambdas { constexpr int foo = [](){return 42;}(); } namespace test::nested_namespace::definitions { } namespace test_fold_expression { template int multiply(Args... args) { return (args * ... * 1); } template bool all(Args... args) { return (args && ...); } } namespace test_extended_static_assert { static_assert (true); } namespace test_auto_brace_init_list { auto foo = {5}; auto bar {5}; static_assert(std::is_same, decltype(foo)>::value); static_assert(std::is_same::value); } namespace test_typename_in_template_template_parameter { template typename X> struct D; } namespace test_fallthrough_nodiscard_maybe_unused_attributes { int f1() { return 42; } [[nodiscard]] int f2() { [[maybe_unused]] auto unused = f1(); switch (f1()) { case 17: f1(); [[fallthrough]]; case 42: f1(); } return f1(); } } namespace test_extended_aggregate_initialization { struct base1 { int b1, b2 = 42; }; struct base2 { base2() { b3 = 42; } int b3; }; struct derived : base1, base2 { int d; }; derived d1 {{1, 2}, {}, 4}; // full initialization derived d2 {{}, {}, 4}; // value-initialized bases } namespace test_general_range_based_for_loop { struct iter { int i; int& operator* () { return i; } const int& operator* () const { return i; } iter& operator++() { ++i; return *this; } }; struct sentinel { int i; }; bool operator== (const iter& i, const sentinel& s) { return i.i == s.i; } bool operator!= (const iter& i, const sentinel& s) { return !(i == s); } struct range { iter begin() const { return {0}; } sentinel end() const { return {5}; } }; void f() { range r {}; for (auto i : r) { [[maybe_unused]] auto v = i; } } } namespace test_lambda_capture_asterisk_this_by_value { struct t { int i; int foo() { return [*this]() { return i; }(); } }; } namespace test_enum_class_construction { enum class byte : unsigned char {}; byte foo {42}; } namespace test_constexpr_if { template int f () { if constexpr(cond) { return 13; } else { return 42; } } } namespace test_selection_statement_with_initializer { int f() { return 13; } int f2() { if (auto i = f(); i > 0) { return 3; } switch (auto i = f(); i + 4) { case 17: return 2; default: return 1; } } } namespace test_template_argument_deduction_for_class_templates { template struct pair { pair (T1 p1, T2 p2) : m1 {p1}, m2 {p2} {} T1 m1; T2 m2; }; void f() { [[maybe_unused]] auto p = pair{13, 42u}; } } namespace test_non_type_auto_template_parameters { template struct B {}; B<5> b1; B<'a'> b2; } namespace test_structured_bindings { int arr[2] = { 1, 2 }; std::pair pr = { 1, 2 }; auto f1() -> int(&)[2] { return arr; } auto f2() -> std::pair& { return pr; } struct S { int x1 : 2; volatile double y1; }; S f3() { return {}; } auto [ x1, y1 ] = f1(); auto& [ xr1, yr1 ] = f1(); auto [ x2, y2 ] = f2(); auto& [ xr2, yr2 ] = f2(); const auto [ x3, y3 ] = f3(); } namespace test_exception_spec_type_system { struct Good {}; struct Bad {}; void g1() noexcept; void g2(); template Bad f(T*, T*); template Good f(T1*, T2*); static_assert (std::is_same_v); } namespace test_inline_variables { template void f(T) {} template inline T g(T) { return T{}; } template<> inline void f<>(int) {} template<> int g<>(int) { return 5; } } } // namespace cxx17 #endif // __cplusplus < 201703L _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : eval $cachevar=yes else $as_nop eval $cachevar=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext CXX="$ac_save_CXX" fi eval ac_res=\$$cachevar { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 printf "%s\n" "$ac_res" >&6; } if eval test x\$$cachevar = xyes; then CXX="$CXX $switch" if test -n "$CXXCPP" ; then CXXCPP="$CXXCPP $switch" fi ac_success=yes break fi done fi if test x$ac_success = xno; then for alternative in ${ax_cxx_compile_alternatives}; do for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}"; do cachevar=`printf "%s\n" "ax_cv_cxx_compile_cxx17_$switch" | $as_tr_sh` { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++17 features with $switch" >&5 printf %s "checking whether $CXX supports C++17 features with $switch... " >&6; } if eval test \${$cachevar+y} then : printf %s "(cached) " >&6 else $as_nop ac_save_CXX="$CXX" CXX="$CXX $switch" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ // If the compiler admits that it is not ready for C++11, why torture it? // Hopefully, this will speed up the test. #ifndef __cplusplus #error "This is not a C++ compiler" #elif __cplusplus < 201103L #error "This is not a C++11 compiler" #else namespace cxx11 { namespace test_static_assert { template struct check { static_assert(sizeof(int) <= sizeof(T), "not big enough"); }; } namespace test_final_override { struct Base { virtual ~Base() {} virtual void f() {} }; struct Derived : public Base { virtual ~Derived() override {} virtual void f() override {} }; } namespace test_double_right_angle_brackets { template < typename T > struct check {}; typedef check single_type; typedef check> double_type; typedef check>> triple_type; typedef check>>> quadruple_type; } namespace test_decltype { int f() { int a = 1; decltype(a) b = 2; return a + b; } } namespace test_type_deduction { template < typename T1, typename T2 > struct is_same { static const bool value = false; }; template < typename T > struct is_same { static const bool value = true; }; template < typename T1, typename T2 > auto add(T1 a1, T2 a2) -> decltype(a1 + a2) { return a1 + a2; } int test(const int c, volatile int v) { static_assert(is_same::value == true, ""); static_assert(is_same::value == false, ""); static_assert(is_same::value == false, ""); auto ac = c; auto av = v; auto sumi = ac + av + 'x'; auto sumf = ac + av + 1.0; static_assert(is_same::value == true, ""); static_assert(is_same::value == true, ""); static_assert(is_same::value == true, ""); static_assert(is_same::value == false, ""); static_assert(is_same::value == true, ""); return (sumf > 0.0) ? sumi : add(c, v); } } namespace test_noexcept { int f() { return 0; } int g() noexcept { return 0; } static_assert(noexcept(f()) == false, ""); static_assert(noexcept(g()) == true, ""); } namespace test_constexpr { template < typename CharT > unsigned long constexpr strlen_c_r(const CharT *const s, const unsigned long acc) noexcept { return *s ? strlen_c_r(s + 1, acc + 1) : acc; } template < typename CharT > unsigned long constexpr strlen_c(const CharT *const s) noexcept { return strlen_c_r(s, 0UL); } static_assert(strlen_c("") == 0UL, ""); static_assert(strlen_c("1") == 1UL, ""); static_assert(strlen_c("example") == 7UL, ""); static_assert(strlen_c("another\0example") == 7UL, ""); } namespace test_rvalue_references { template < int N > struct answer { static constexpr int value = N; }; answer<1> f(int&) { return answer<1>(); } answer<2> f(const int&) { return answer<2>(); } answer<3> f(int&&) { return answer<3>(); } void test() { int i = 0; const int c = 0; static_assert(decltype(f(i))::value == 1, ""); static_assert(decltype(f(c))::value == 2, ""); static_assert(decltype(f(0))::value == 3, ""); } } namespace test_uniform_initialization { struct test { static const int zero {}; static const int one {1}; }; static_assert(test::zero == 0, ""); static_assert(test::one == 1, ""); } namespace test_lambdas { void test1() { auto lambda1 = [](){}; auto lambda2 = lambda1; lambda1(); lambda2(); } int test2() { auto a = [](int i, int j){ return i + j; }(1, 2); auto b = []() -> int { return '0'; }(); auto c = [=](){ return a + b; }(); auto d = [&](){ return c; }(); auto e = [a, &b](int x) mutable { const auto identity = [](int y){ return y; }; for (auto i = 0; i < a; ++i) a += b--; return x + identity(a + b); }(0); return a + b + c + d + e; } int test3() { const auto nullary = [](){ return 0; }; const auto unary = [](int x){ return x; }; using nullary_t = decltype(nullary); using unary_t = decltype(unary); const auto higher1st = [](nullary_t f){ return f(); }; const auto higher2nd = [unary](nullary_t f1){ return [unary, f1](unary_t f2){ return f2(unary(f1())); }; }; return higher1st(nullary) + higher2nd(nullary)(unary); } } namespace test_variadic_templates { template struct sum; template struct sum { static constexpr auto value = N0 + sum::value; }; template <> struct sum<> { static constexpr auto value = 0; }; static_assert(sum<>::value == 0, ""); static_assert(sum<1>::value == 1, ""); static_assert(sum<23>::value == 23, ""); static_assert(sum<1, 2>::value == 3, ""); static_assert(sum<5, 5, 11>::value == 21, ""); static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); } // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function // because of this. namespace test_template_alias_sfinae { struct foo {}; template using member = typename T::member_type; template void func(...) {} template void func(member*) {} void test(); void test() { func(0); } } } // namespace cxx11 #endif // __cplusplus >= 201103L // If the compiler admits that it is not ready for C++14, why torture it? // Hopefully, this will speed up the test. #ifndef __cplusplus #error "This is not a C++ compiler" #elif __cplusplus < 201402L #error "This is not a C++14 compiler" #else namespace cxx14 { namespace test_polymorphic_lambdas { int test() { const auto lambda = [](auto&&... args){ const auto istiny = [](auto x){ return (sizeof(x) == 1UL) ? 1 : 0; }; const int aretiny[] = { istiny(args)... }; return aretiny[0]; }; return lambda(1, 1L, 1.0f, '1'); } } namespace test_binary_literals { constexpr auto ivii = 0b0000000000101010; static_assert(ivii == 42, "wrong value"); } namespace test_generalized_constexpr { template < typename CharT > constexpr unsigned long strlen_c(const CharT *const s) noexcept { auto length = 0UL; for (auto p = s; *p; ++p) ++length; return length; } static_assert(strlen_c("") == 0UL, ""); static_assert(strlen_c("x") == 1UL, ""); static_assert(strlen_c("test") == 4UL, ""); static_assert(strlen_c("another\0test") == 7UL, ""); } namespace test_lambda_init_capture { int test() { auto x = 0; const auto lambda1 = [a = x](int b){ return a + b; }; const auto lambda2 = [a = lambda1(x)](){ return a; }; return lambda2(); } } namespace test_digit_separators { constexpr auto ten_million = 100'000'000; static_assert(ten_million == 100000000, ""); } namespace test_return_type_deduction { auto f(int& x) { return x; } decltype(auto) g(int& x) { return x; } template < typename T1, typename T2 > struct is_same { static constexpr auto value = false; }; template < typename T > struct is_same { static constexpr auto value = true; }; int test() { auto x = 0; static_assert(is_same::value, ""); static_assert(is_same::value, ""); return x; } } } // namespace cxx14 #endif // __cplusplus >= 201402L // If the compiler admits that it is not ready for C++17, why torture it? // Hopefully, this will speed up the test. #ifndef __cplusplus #error "This is not a C++ compiler" #elif __cplusplus < 201703L #error "This is not a C++17 compiler" #else #include #include #include namespace cxx17 { namespace test_constexpr_lambdas { constexpr int foo = [](){return 42;}(); } namespace test::nested_namespace::definitions { } namespace test_fold_expression { template int multiply(Args... args) { return (args * ... * 1); } template bool all(Args... args) { return (args && ...); } } namespace test_extended_static_assert { static_assert (true); } namespace test_auto_brace_init_list { auto foo = {5}; auto bar {5}; static_assert(std::is_same, decltype(foo)>::value); static_assert(std::is_same::value); } namespace test_typename_in_template_template_parameter { template typename X> struct D; } namespace test_fallthrough_nodiscard_maybe_unused_attributes { int f1() { return 42; } [[nodiscard]] int f2() { [[maybe_unused]] auto unused = f1(); switch (f1()) { case 17: f1(); [[fallthrough]]; case 42: f1(); } return f1(); } } namespace test_extended_aggregate_initialization { struct base1 { int b1, b2 = 42; }; struct base2 { base2() { b3 = 42; } int b3; }; struct derived : base1, base2 { int d; }; derived d1 {{1, 2}, {}, 4}; // full initialization derived d2 {{}, {}, 4}; // value-initialized bases } namespace test_general_range_based_for_loop { struct iter { int i; int& operator* () { return i; } const int& operator* () const { return i; } iter& operator++() { ++i; return *this; } }; struct sentinel { int i; }; bool operator== (const iter& i, const sentinel& s) { return i.i == s.i; } bool operator!= (const iter& i, const sentinel& s) { return !(i == s); } struct range { iter begin() const { return {0}; } sentinel end() const { return {5}; } }; void f() { range r {}; for (auto i : r) { [[maybe_unused]] auto v = i; } } } namespace test_lambda_capture_asterisk_this_by_value { struct t { int i; int foo() { return [*this]() { return i; }(); } }; } namespace test_enum_class_construction { enum class byte : unsigned char {}; byte foo {42}; } namespace test_constexpr_if { template int f () { if constexpr(cond) { return 13; } else { return 42; } } } namespace test_selection_statement_with_initializer { int f() { return 13; } int f2() { if (auto i = f(); i > 0) { return 3; } switch (auto i = f(); i + 4) { case 17: return 2; default: return 1; } } } namespace test_template_argument_deduction_for_class_templates { template struct pair { pair (T1 p1, T2 p2) : m1 {p1}, m2 {p2} {} T1 m1; T2 m2; }; void f() { [[maybe_unused]] auto p = pair{13, 42u}; } } namespace test_non_type_auto_template_parameters { template struct B {}; B<5> b1; B<'a'> b2; } namespace test_structured_bindings { int arr[2] = { 1, 2 }; std::pair pr = { 1, 2 }; auto f1() -> int(&)[2] { return arr; } auto f2() -> std::pair& { return pr; } struct S { int x1 : 2; volatile double y1; }; S f3() { return {}; } auto [ x1, y1 ] = f1(); auto& [ xr1, yr1 ] = f1(); auto [ x2, y2 ] = f2(); auto& [ xr2, yr2 ] = f2(); const auto [ x3, y3 ] = f3(); } namespace test_exception_spec_type_system { struct Good {}; struct Bad {}; void g1() noexcept; void g2(); template Bad f(T*, T*); template Good f(T1*, T2*); static_assert (std::is_same_v); } namespace test_inline_variables { template void f(T) {} template inline T g(T) { return T{}; } template<> inline void f<>(int) {} template<> int g<>(int) { return 5; } } } // namespace cxx17 #endif // __cplusplus < 201703L _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : eval $cachevar=yes else $as_nop eval $cachevar=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext CXX="$ac_save_CXX" fi eval ac_res=\$$cachevar { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 printf "%s\n" "$ac_res" >&6; } if eval test x\$$cachevar = xyes; then CXX="$CXX $switch" if test -n "$CXXCPP" ; then CXXCPP="$CXXCPP $switch" fi ac_success=yes break fi done if test x$ac_success = xyes; then break fi done fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test x$ax_cxx_compile_cxx17_required = xtrue; then if test x$ac_success = xno; then as_fn_error $? "*** A compiler with support for C++17 language features is required." "$LINENO" 5 fi fi if test x$ac_success = xno; then HAVE_CXX17=0 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: No compiler with C++17 support was found" >&5 printf "%s\n" "$as_me: No compiler with C++17 support was found" >&6;} else HAVE_CXX17=1 printf "%s\n" "#define HAVE_CXX17 1" >>confdefs.h fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 printf %s "checking whether ln -s works... " >&6; } LN_S=$as_ln_s if test "$LN_S" = "ln -s"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 printf "%s\n" "no, using $LN_S" >&6; } fi if test "$ac_cv_prog_cc_c99" = "no"; then as_fn_error $? "Need a C99 compiler" "$LINENO" 5 fi # autoscan start # Checks for header files. ac_fn_c_check_header_compile "$LINENO" "fcntl.h" "ac_cv_header_fcntl_h" "$ac_includes_default" if test "x$ac_cv_header_fcntl_h" = xyes then : printf "%s\n" "#define HAVE_FCNTL_H 1" >>confdefs.h fi ac_fn_c_check_header_compile "$LINENO" "stdlib.h" "ac_cv_header_stdlib_h" "$ac_includes_default" if test "x$ac_cv_header_stdlib_h" = xyes then : printf "%s\n" "#define HAVE_STDLIB_H 1" >>confdefs.h fi ac_fn_c_check_header_compile "$LINENO" "sys/time.h" "ac_cv_header_sys_time_h" "$ac_includes_default" if test "x$ac_cv_header_sys_time_h" = xyes then : printf "%s\n" "#define HAVE_SYS_TIME_H 1" >>confdefs.h fi ac_fn_c_check_header_compile "$LINENO" "errno.h" "ac_cv_header_errno_h" "$ac_includes_default" if test "x$ac_cv_header_errno_h" = xyes then : printf "%s\n" "#define HAVE_ERRNO_H 1" >>confdefs.h fi ac_fn_c_check_header_compile "$LINENO" "limits.h" "ac_cv_header_limits_h" "$ac_includes_default" if test "x$ac_cv_header_limits_h" = xyes then : printf "%s\n" "#define HAVE_LIMITS_H 1" >>confdefs.h fi # Checks for dependencies needed by ctags ac_fn_c_check_header_compile "$LINENO" "dirent.h" "ac_cv_header_dirent_h" "$ac_includes_default" if test "x$ac_cv_header_dirent_h" = xyes then : printf "%s\n" "#define HAVE_DIRENT_H 1" >>confdefs.h fi ac_fn_c_check_header_compile "$LINENO" "fnmatch.h" "ac_cv_header_fnmatch_h" "$ac_includes_default" if test "x$ac_cv_header_fnmatch_h" = xyes then : printf "%s\n" "#define HAVE_FNMATCH_H 1" >>confdefs.h fi ac_fn_c_check_header_compile "$LINENO" "direct.h" "ac_cv_header_direct_h" "$ac_includes_default" if test "x$ac_cv_header_direct_h" = xyes then : printf "%s\n" "#define HAVE_DIRECT_H 1" >>confdefs.h fi ac_fn_c_check_header_compile "$LINENO" "io.h" "ac_cv_header_io_h" "$ac_includes_default" if test "x$ac_cv_header_io_h" = xyes then : printf "%s\n" "#define HAVE_IO_H 1" >>confdefs.h fi ac_fn_c_check_header_compile "$LINENO" "sys/dir.h" "ac_cv_header_sys_dir_h" "$ac_includes_default" if test "x$ac_cv_header_sys_dir_h" = xyes then : printf "%s\n" "#define HAVE_SYS_DIR_H 1" >>confdefs.h fi printf "%s\n" "#define HAVE_STDBOOL_H 1" >>confdefs.h ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" if test "x$ac_cv_type_size_t" = xyes then : else $as_nop printf "%s\n" "#define size_t unsigned int" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "regcomp" "ac_cv_func_regcomp" if test "x$ac_cv_func_regcomp" = xyes then : have_regcomp=yes else $as_nop have_regcomp=no ac_fn_c_check_header_compile "$LINENO" "langinfo.h" "ac_cv_header_langinfo_h" "$ac_includes_default" if test "x$ac_cv_header_langinfo_h" = xyes then : printf "%s\n" "#define HAVE_LANGINFO_H 1" >>confdefs.h fi ac_fn_c_check_header_compile "$LINENO" "locale.h" "ac_cv_header_locale_h" "$ac_includes_default" if test "x$ac_cv_header_locale_h" = xyes then : printf "%s\n" "#define HAVE_LOCALE_H 1" >>confdefs.h fi ac_fn_c_check_header_compile "$LINENO" "libintl.h" "ac_cv_header_libintl_h" "$ac_includes_default" if test "x$ac_cv_header_libintl_h" = xyes then : printf "%s\n" "#define HAVE_LIBINTL_H 1" >>confdefs.h fi ac_fn_c_check_header_compile "$LINENO" "wctype.h" "ac_cv_header_wctype_h" "$ac_includes_default" if test "x$ac_cv_header_wctype_h" = xyes then : printf "%s\n" "#define HAVE_WCTYPE_H 1" >>confdefs.h fi ac_fn_c_check_header_compile "$LINENO" "wchar.h" "ac_cv_header_wchar_h" "$ac_includes_default" if test "x$ac_cv_header_wchar_h" = xyes then : printf "%s\n" "#define HAVE_WCHAR_H 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "memcpy" "ac_cv_func_memcpy" if test "x$ac_cv_func_memcpy" = xyes then : printf "%s\n" "#define HAVE_MEMCPY 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "isblank" "ac_cv_func_isblank" if test "x$ac_cv_func_isblank" = xyes then : printf "%s\n" "#define HAVE_ISBLANK 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "wcrtomb" "ac_cv_func_wcrtomb" if test "x$ac_cv_func_wcrtomb" = xyes then : printf "%s\n" "#define HAVE_WCRTOMB 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "mbrtowc" "ac_cv_func_mbrtowc" if test "x$ac_cv_func_mbrtowc" = xyes then : printf "%s\n" "#define HAVE_MBRTOWC 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "wcscoll" "ac_cv_func_wcscoll" if test "x$ac_cv_func_wcscoll" = xyes then : printf "%s\n" "#define HAVE_WCSCOLL 1" >>confdefs.h fi # The Ultrix 4.2 mips builtin alloca declared by alloca.h only works # for constant arguments. Useless! { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for working alloca.h" >&5 printf %s "checking for working alloca.h... " >&6; } if test ${ac_cv_working_alloca_h+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main (void) { char *p = (char *) alloca (2 * sizeof (int)); if (p) return 0; ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_working_alloca_h=yes else $as_nop ac_cv_working_alloca_h=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_working_alloca_h" >&5 printf "%s\n" "$ac_cv_working_alloca_h" >&6; } if test $ac_cv_working_alloca_h = yes; then printf "%s\n" "#define HAVE_ALLOCA_H 1" >>confdefs.h fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for alloca" >&5 printf %s "checking for alloca... " >&6; } if test ${ac_cv_func_alloca_works+y} then : printf %s "(cached) " >&6 else $as_nop if test $ac_cv_working_alloca_h = yes; then ac_cv_func_alloca_works=yes else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #ifndef alloca # ifdef __GNUC__ # define alloca __builtin_alloca # elif defined _MSC_VER # include # define alloca _alloca # else # ifdef __cplusplus extern "C" # endif void *alloca (size_t); # endif #endif int main (void) { char *p = (char *) alloca (1); if (p) return 0; ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_func_alloca_works=yes else $as_nop ac_cv_func_alloca_works=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_alloca_works" >&5 printf "%s\n" "$ac_cv_func_alloca_works" >&6; } fi if test $ac_cv_func_alloca_works = yes; then printf "%s\n" "#define HAVE_ALLOCA 1" >>confdefs.h else # The SVR3 libPW and SVR4 libucb both contain incompatible functions # that cause trouble. Some versions do not even contain alloca or # contain a buggy version. If you still want to use their alloca, # use ar to extract alloca.o from them instead of compiling alloca.c. ALLOCA=\${LIBOBJDIR}alloca.$ac_objext printf "%s\n" "#define C_ALLOCA 1" >>confdefs.h { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking stack direction for C alloca" >&5 printf %s "checking stack direction for C alloca... " >&6; } if test ${ac_cv_c_stack_direction+y} then : printf %s "(cached) " >&6 else $as_nop if test "$cross_compiling" = yes then : ac_cv_c_stack_direction=0 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default int find_stack_direction (int *addr, int depth) { int dir, dummy = 0; if (! addr) addr = &dummy; *addr = addr < &dummy ? 1 : addr == &dummy ? 0 : -1; dir = depth ? find_stack_direction (addr, depth - 1) : 0; return dir + dummy; } int main (int argc, char **argv) { return find_stack_direction (0, argc + !argv + 20) < 0; } _ACEOF if ac_fn_c_try_run "$LINENO" then : ac_cv_c_stack_direction=1 else $as_nop ac_cv_c_stack_direction=-1 fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_stack_direction" >&5 printf "%s\n" "$ac_cv_c_stack_direction" >&6; } printf "%s\n" "#define STACK_DIRECTION $ac_cv_c_stack_direction" >>confdefs.h fi fi if test "xno" = "x$have_regcomp"; then USE_BUNDLED_REGEX_TRUE= USE_BUNDLED_REGEX_FALSE='#' else USE_BUNDLED_REGEX_TRUE='#' USE_BUNDLED_REGEX_FALSE= fi ac_fn_c_check_func "$LINENO" "fnmatch" "ac_cv_func_fnmatch" if test "x$ac_cv_func_fnmatch" = xyes then : have_fnmatch=yes else $as_nop have_fnmatch=no fi if test "xno" = "x$have_fnmatch"; then USE_BUNDLED_FNMATCH_TRUE= USE_BUNDLED_FNMATCH_FALSE='#' else USE_BUNDLED_FNMATCH_TRUE='#' USE_BUNDLED_FNMATCH_FALSE= fi # Checks for typedefs, structures, and compiler characteristics. ac_fn_c_check_type "$LINENO" "off_t" "ac_cv_type_off_t" "$ac_includes_default" if test "x$ac_cv_type_off_t" = xyes then : else $as_nop printf "%s\n" "#define off_t long int" >>confdefs.h fi ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" if test "x$ac_cv_type_size_t" = xyes then : else $as_nop printf "%s\n" "#define size_t unsigned int" >>confdefs.h fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether struct tm is in sys/time.h or time.h" >&5 printf %s "checking whether struct tm is in sys/time.h or time.h... " >&6; } if test ${ac_cv_struct_tm+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main (void) { struct tm tm; int *p = &tm.tm_sec; return !p; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_cv_struct_tm=time.h else $as_nop ac_cv_struct_tm=sys/time.h fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_struct_tm" >&5 printf "%s\n" "$ac_cv_struct_tm" >&6; } if test $ac_cv_struct_tm = sys/time.h; then printf "%s\n" "#define TM_IN_SYS_TIME 1" >>confdefs.h fi # Checks for library functions. ac_fn_c_check_func "$LINENO" "realpath" "ac_cv_func_realpath" if test "x$ac_cv_func_realpath" = xyes then : printf "%s\n" "#define HAVE_REALPATH 1" >>confdefs.h fi # Function checks for u-ctags ac_fn_c_check_func "$LINENO" "strerror" "ac_cv_func_strerror" if test "x$ac_cv_func_strerror" = xyes then : printf "%s\n" "#define HAVE_STRERROR 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "strstr" "ac_cv_func_strstr" if test "x$ac_cv_func_strstr" = xyes then : printf "%s\n" "#define HAVE_STRSTR 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "asprintf" "ac_cv_func_asprintf" if test "x$ac_cv_func_asprintf" = xyes then : printf "%s\n" "#define HAVE_ASPRINTF 1" >>confdefs.h fi for ac_func in mkstemp tempnam do : as_ac_var=`printf "%s\n" "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes" then : cat >>confdefs.h <<_ACEOF #define `printf "%s\n" "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF break fi done for ac_func in strcasecmp stricmp do : as_ac_var=`printf "%s\n" "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes" then : cat >>confdefs.h <<_ACEOF #define `printf "%s\n" "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF break fi done for ac_func in strncasecmp strnicmp do : as_ac_var=`printf "%s\n" "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes" then : cat >>confdefs.h <<_ACEOF #define `printf "%s\n" "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF break fi done for ac_func in truncate ftruncate chsize do : as_ac_var=`printf "%s\n" "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes" then : cat >>confdefs.h <<_ACEOF #define `printf "%s\n" "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF break fi done # non-functions checks for u-ctags. Not that we really need those as we don't # use u-ctags's main, but the corresponding macros have to be defined to # something, so simply perform the actual checks. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC options needed to detect all undeclared functions" >&5 printf %s "checking for $CC options needed to detect all undeclared functions... " >&6; } if test ${ac_cv_c_undeclared_builtin_options+y} then : printf %s "(cached) " >&6 else $as_nop ac_save_CFLAGS=$CFLAGS ac_cv_c_undeclared_builtin_options='cannot detect' for ac_arg in '' -fno-builtin; do CFLAGS="$ac_save_CFLAGS $ac_arg" # This test program should *not* compile successfully. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { (void) strchr; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : else $as_nop # This test program should compile successfully. # No library function is consistently available on # freestanding implementations, so test against a dummy # declaration. Include always-available headers on the # off chance that they somehow elicit warnings. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include extern void ac_decl (int, char *); int main (void) { (void) ac_decl (0, (char *) 0); (void) ac_decl; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : if test x"$ac_arg" = x then : ac_cv_c_undeclared_builtin_options='none needed' else $as_nop ac_cv_c_undeclared_builtin_options=$ac_arg fi break fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext done CFLAGS=$ac_save_CFLAGS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_undeclared_builtin_options" >&5 printf "%s\n" "$ac_cv_c_undeclared_builtin_options" >&6; } case $ac_cv_c_undeclared_builtin_options in #( 'cannot detect') : { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot make $CC report undeclared builtins See \`config.log' for more details" "$LINENO" 5; } ;; #( 'none needed') : ac_c_undeclared_builtin_options='' ;; #( *) : ac_c_undeclared_builtin_options=$ac_cv_c_undeclared_builtin_options ;; esac ac_fn_check_decl "$LINENO" "__environ" "ac_cv_have_decl___environ" "#include " "$ac_c_undeclared_builtin_options" "CFLAGS" if test "x$ac_cv_have_decl___environ" = xyes then : ac_have_decl=1 else $as_nop ac_have_decl=0 fi printf "%s\n" "#define HAVE_DECL___ENVIRON $ac_have_decl" >>confdefs.h ac_fn_check_decl "$LINENO" "_NSGetEnviron" "ac_cv_have_decl__NSGetEnviron" "#include " "$ac_c_undeclared_builtin_options" "CFLAGS" if test "x$ac_cv_have_decl__NSGetEnviron" = xyes then : ac_have_decl=1 else $as_nop ac_have_decl=0 fi printf "%s\n" "#define HAVE_DECL__NSGETENVIRON $ac_have_decl" >>confdefs.h # autoscan end # check for VCS revision REVISION="0" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Git revision" >&5 printf %s "checking for Git revision... " >&6; } # try Git first GIT=`which git 2>/dev/null` if test -d "$srcdir/.git" -a "x${GIT}" != "x" -a -x "${GIT}"; then REVISION=`cd "$srcdir"; "${GIT}" rev-parse --short --revs-only HEAD 2>/dev/null || echo 0` fi if test "x${REVISION}" != "x0"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $REVISION" >&5 printf "%s\n" "$REVISION" >&6; } _GEANY_STATUS="$_GEANY_STATUS Compiling Git revision:$REVISION" # call action-if-found CFLAGS="-g -DGEANY_DEBUG $CFLAGS" else REVISION="-1" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none" >&5 printf "%s\n" "none" >&6; } # call action-if-not-found fi printf "%s\n" "#define REVISION \"$REVISION\"" >>confdefs.h if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_path_PKG_CONFIG+y} then : printf %s "(cached) " >&6 else $as_nop case $PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_path_PKG_CONFIG="$as_dir$ac_word$ac_exec_ext" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi PKG_CONFIG=$ac_cv_path_PKG_CONFIG if test -n "$PKG_CONFIG"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 printf "%s\n" "$PKG_CONFIG" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_path_PKG_CONFIG"; then ac_pt_PKG_CONFIG=$PKG_CONFIG # Extract the first word of "pkg-config", so it can be a program name with args. set dummy pkg-config; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_path_ac_pt_PKG_CONFIG+y} then : printf %s "(cached) " >&6 else $as_nop case $ac_pt_PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_path_ac_pt_PKG_CONFIG="$as_dir$ac_word$ac_exec_ext" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG if test -n "$ac_pt_PKG_CONFIG"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 printf "%s\n" "$ac_pt_PKG_CONFIG" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_pt_PKG_CONFIG" = x; then PKG_CONFIG="" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac PKG_CONFIG=$ac_pt_PKG_CONFIG fi else PKG_CONFIG="$ac_cv_path_PKG_CONFIG" fi fi if test -n "$PKG_CONFIG"; then _pkg_min_version=0.9.0 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 printf %s "checking pkg-config is at least version $_pkg_min_version... " >&6; } if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } PKG_CONFIG="" fi fi gtk_modules="gtk+-3.0 >= 3.24 glib-2.0 >= 2.32" gtk_modules_private="gio-2.0 >= 2.32 gmodule-no-export-2.0 gthread-2.0" pkg_failed=no { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $gtk_modules $gtk_modules_private" >&5 printf %s "checking for $gtk_modules $gtk_modules_private... " >&6; } if test -n "$GTK_CFLAGS"; then pkg_cv_GTK_CFLAGS="$GTK_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$gtk_modules \$gtk_modules_private\""; } >&5 ($PKG_CONFIG --exists --print-errors "$gtk_modules $gtk_modules_private") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_GTK_CFLAGS=`$PKG_CONFIG --cflags "$gtk_modules $gtk_modules_private" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$GTK_LIBS"; then pkg_cv_GTK_LIBS="$GTK_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$gtk_modules \$gtk_modules_private\""; } >&5 ($PKG_CONFIG --exists --print-errors "$gtk_modules $gtk_modules_private") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_GTK_LIBS=`$PKG_CONFIG --libs "$gtk_modules $gtk_modules_private" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then GTK_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$gtk_modules $gtk_modules_private" 2>&1` else GTK_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$gtk_modules $gtk_modules_private" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$GTK_PKG_ERRORS" >&5 as_fn_error $? "Package requirements ($gtk_modules $gtk_modules_private) were not met: $GTK_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. Alternatively, you may set the environment variables GTK_CFLAGS and GTK_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details." "$LINENO" 5 elif test $pkg_failed = untried; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. Alternatively, you may set the environment variables GTK_CFLAGS and GTK_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details. To get pkg-config, see . See \`config.log' for more details" "$LINENO" 5; } else GTK_CFLAGS=$pkg_cv_GTK_CFLAGS GTK_LIBS=$pkg_cv_GTK_LIBS { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } fi DEPENDENCIES=$gtk_modules as_fn_append GTK_CFLAGS " -DGLIB_VERSION_MIN_REQUIRED=GLIB_VERSION_2_32" as_fn_append GTK_CFLAGS " -DGDK_DISABLE_DEPRECATION_WARNINGS" GTK_VERSION=`$PKG_CONFIG --modversion gtk+-3.0` _GEANY_STATUS="$_GEANY_STATUS Using GTK version:${GTK_VERSION}" CFLAGS_save=$CFLAGS CFLAGS=$GTK_CFLAGS LIBS_save=$LIBS LIBS=$GTK_LIBS ac_fn_c_check_func "$LINENO" "g_strv_equal" "ac_cv_func_g_strv_equal" if test "x$ac_cv_func_g_strv_equal" = xyes then : printf "%s\n" "#define HAVE_G_STRV_EQUAL 1" >>confdefs.h fi CFLAGS=$CFLAGS_save LIBS=$LIBS_save # --disable-deprecated switch for GTK purification # Check whether --enable-deprecated was given. if test ${enable_deprecated+y} then : enableval=$enable_deprecated; GTK_CFLAGS="$GTK_CFLAGS -DG_DISABLE_DEPRECATED -DGTK_DISABLE_DEPRECATED" fi # Check for binary relocation support # Check whether --enable-binreloc was given. if test ${enable_binreloc+y} then : enableval=$enable_binreloc; enable_binreloc=$enableval else $as_nop enable_binreloc=no fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether binary relocation support should be enabled" >&5 printf %s "checking whether binary relocation support should be enabled... " >&6; } if test "$enable_binreloc" = "yes"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for linker mappings at /proc/self/maps" >&5 printf %s "checking for linker mappings at /proc/self/maps... " >&6; } if test -e /proc/self/maps; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } as_fn_error $? "/proc/self/maps is not available. Binary relocation cannot be enabled." "$LINENO" 5 enable_binreloc="no" fi elif test "$enable_binreloc" = "auto"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes when available" >&5 printf "%s\n" "yes when available" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for linker mappings at /proc/self/maps" >&5 printf %s "checking for linker mappings at /proc/self/maps... " >&6; } if test -e /proc/self/maps; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } enable_binreloc=yes { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether everything is installed to the same prefix" >&5 printf %s "checking whether everything is installed to the same prefix... " >&6; } if test "$bindir" = '${exec_prefix}/bin' -a "$sbindir" = '${exec_prefix}/sbin' -a \ "$datadir" = '${prefix}/share' -a "$libdir" = '${exec_prefix}/lib' -a \ "$libexecdir" = '${exec_prefix}/libexec' -a "$sysconfdir" = '${prefix}/etc' then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Binary relocation support will be disabled." >&5 printf "%s\n" "$as_me: Binary relocation support will be disabled." >&6;} enable_binreloc=no fi else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } enable_binreloc=no fi elif test "$enable_binreloc" = "no"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no (unknown value \"$enable_binreloc\")" >&5 printf "%s\n" "no (unknown value \"$enable_binreloc\")" >&6; } enable_binreloc=no fi if test "$enable_binreloc" = "yes"; then ENABLE_BINRELOC_TRUE= ENABLE_BINRELOC_FALSE='#' else ENABLE_BINRELOC_TRUE='#' ENABLE_BINRELOC_FALSE= fi if test -z "$ENABLE_BINRELOC_TRUE"; then : printf "%s\n" "#define ENABLE_BINRELOC /**/" >>confdefs.h fi _GEANY_STATUS="$_GEANY_STATUS Enable binary relocation:$enable_binreloc" # CTags source compatibility (we actually use GRegex instead of POSIX regcomp) printf "%s\n" "#define HAVE_REGCOMP 1" >>confdefs.h # Plugins support # Check whether --enable-static was given. if test ${enable_static+y} then : enableval=$enable_static; p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS=$lt_save_ifs ;; esac else $as_nop enable_static=no fi # Check whether --enable-plugins was given. if test ${enable_plugins+y} then : enableval=$enable_plugins; geany_enable_plugins=$enableval else $as_nop geany_enable_plugins=yes fi case "$LIBTOOL" in #( *--silent*) : ;; #( *) : LIBTOOL="$LIBTOOL --silent" ;; esac if test "x$geany_enable_plugins" = "xyes" ; then printf "%s\n" "#define HAVE_PLUGINS 1" >>confdefs.h if true; then PLUGINS_TRUE= PLUGINS_FALSE='#' else PLUGINS_TRUE='#' PLUGINS_FALSE= fi else if false; then PLUGINS_TRUE= PLUGINS_FALSE='#' else PLUGINS_TRUE='#' PLUGINS_FALSE= fi fi _GEANY_STATUS="$_GEANY_STATUS Build with plugin support:$geany_enable_plugins" # check for mingw specific settings # Check whether --enable-vte was given. if test ${enable_vte+y} then : enableval=$enable_vte; geany_enable_vte="$enableval" else $as_nop geany_enable_vte="yes" fi # Check whether --with-vte-module-path was given. if test ${with_vte_module_path+y} then : withval=$with_vte_module_path; printf "%s\n" "#define VTE_MODULE_PATH \"$withval\"" >>confdefs.h fi # Check whether --enable-socket was given. if test ${enable_socket+y} then : enableval=$enable_socket; geany_enable_socket="$enableval" else $as_nop geany_enable_socket="auto" fi case "${host}" in *mingw*) printf "%s\n" "#define WIN32 1" >>confdefs.h if test "x$_geany_enable_vte_done" = x; then if test -n "no"; then geany_enable_vte="no" elif test "x$geany_enable_vte" = xauto; then geany_enable_vte=yes fi if test "x$geany_enable_vte" = xyes; then printf "%s\n" "#define HAVE_VTE 1" >>confdefs.h fi _GEANY_STATUS="$_GEANY_STATUS Use virtual terminal support (VTE):$geany_enable_vte" _geany_enable_vte_done=yes fi if test "x$_geany_enable_socket_done" = x; then if test -n "yes"; then geany_enable_socket="yes" elif test "x$geany_enable_socket" = xauto; then geany_enable_socket=yes fi if test "x$geany_enable_socket" = xyes; then printf "%s\n" "#define HAVE_SOCKET 1" >>confdefs.h # this should bring in libsocket on Solaris: { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing connect" >&5 printf %s "checking for library containing connect... " >&6; } if test ${ac_cv_search_connect+y} then : printf %s "(cached) " >&6 else $as_nop ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char connect (); int main (void) { return connect (); ; return 0; } _ACEOF for ac_lib in '' socket do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO" then : ac_cv_search_connect=$ac_res fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext if test ${ac_cv_search_connect+y} then : break fi done if test ${ac_cv_search_connect+y} then : else $as_nop ac_cv_search_connect=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_connect" >&5 printf "%s\n" "$ac_cv_search_connect" >&6; } ac_res=$ac_cv_search_connect if test "$ac_res" != no then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi fi _GEANY_STATUS="$_GEANY_STATUS Use (UNIX domain) socket support:$geany_enable_socket" _geany_enable_socket_done=yes fi if true; then MINGW_TRUE= MINGW_FALSE='#' else MINGW_TRUE='#' MINGW_FALSE= fi ;; *) if false; then MINGW_TRUE= MINGW_FALSE='#' else MINGW_TRUE='#' MINGW_FALSE= fi ;; esac if test "x$_geany_enable_socket_done" = x; then if test -n ""; then geany_enable_socket="" elif test "x$geany_enable_socket" = xauto; then geany_enable_socket=yes fi if test "x$geany_enable_socket" = xyes; then printf "%s\n" "#define HAVE_SOCKET 1" >>confdefs.h # this should bring in libsocket on Solaris: { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing connect" >&5 printf %s "checking for library containing connect... " >&6; } if test ${ac_cv_search_connect+y} then : printf %s "(cached) " >&6 else $as_nop ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char connect (); int main (void) { return connect (); ; return 0; } _ACEOF for ac_lib in '' socket do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO" then : ac_cv_search_connect=$ac_res fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext if test ${ac_cv_search_connect+y} then : break fi done if test ${ac_cv_search_connect+y} then : else $as_nop ac_cv_search_connect=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_connect" >&5 printf "%s\n" "$ac_cv_search_connect" >&6; } ac_res=$ac_cv_search_connect if test "$ac_res" != no then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi fi _GEANY_STATUS="$_GEANY_STATUS Use (UNIX domain) socket support:$geany_enable_socket" _geany_enable_socket_done=yes fi if test "x$_geany_enable_vte_done" = x; then if test -n ""; then geany_enable_vte="" elif test "x$geany_enable_vte" = xauto; then geany_enable_vte=yes fi if test "x$geany_enable_vte" = xyes; then printf "%s\n" "#define HAVE_VTE 1" >>confdefs.h fi _GEANY_STATUS="$_GEANY_STATUS Use virtual terminal support (VTE):$geany_enable_vte" _geany_enable_vte_done=yes fi # Check whether --enable-mac-integration was given. if test ${enable_mac_integration+y} then : enableval=$enable_mac_integration; geany_enable_mac_integration="$enableval" else $as_nop geany_enable_mac_integration="no" fi if test "x$geany_enable_mac_integration" = "xyes"; then ENABLE_MAC_INTEGRATION_TRUE= ENABLE_MAC_INTEGRATION_FALSE='#' else ENABLE_MAC_INTEGRATION_TRUE='#' ENABLE_MAC_INTEGRATION_FALSE= fi if test -z "$ENABLE_MAC_INTEGRATION_TRUE"; then : pkg_failed=no { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for gtk-mac-integration-gtk3" >&5 printf %s "checking for gtk-mac-integration-gtk3... " >&6; } if test -n "$MAC_INTEGRATION_CFLAGS"; then pkg_cv_MAC_INTEGRATION_CFLAGS="$MAC_INTEGRATION_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gtk-mac-integration-gtk3\""; } >&5 ($PKG_CONFIG --exists --print-errors "gtk-mac-integration-gtk3") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_MAC_INTEGRATION_CFLAGS=`$PKG_CONFIG --cflags "gtk-mac-integration-gtk3" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$MAC_INTEGRATION_LIBS"; then pkg_cv_MAC_INTEGRATION_LIBS="$MAC_INTEGRATION_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gtk-mac-integration-gtk3\""; } >&5 ($PKG_CONFIG --exists --print-errors "gtk-mac-integration-gtk3") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_MAC_INTEGRATION_LIBS=`$PKG_CONFIG --libs "gtk-mac-integration-gtk3" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then MAC_INTEGRATION_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "gtk-mac-integration-gtk3" 2>&1` else MAC_INTEGRATION_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "gtk-mac-integration-gtk3" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$MAC_INTEGRATION_PKG_ERRORS" >&5 as_fn_error $? "Package requirements (gtk-mac-integration-gtk3) were not met: $MAC_INTEGRATION_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. Alternatively, you may set the environment variables MAC_INTEGRATION_CFLAGS and MAC_INTEGRATION_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details." "$LINENO" 5 elif test $pkg_failed = untried; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. Alternatively, you may set the environment variables MAC_INTEGRATION_CFLAGS and MAC_INTEGRATION_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details. To get pkg-config, see . See \`config.log' for more details" "$LINENO" 5; } else MAC_INTEGRATION_CFLAGS=$pkg_cv_MAC_INTEGRATION_CFLAGS MAC_INTEGRATION_LIBS=$pkg_cv_MAC_INTEGRATION_LIBS { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } fi fi # Check whether --enable-the-force was given. if test ${enable_the_force+y} then : enableval=$enable_the_force; be_luke="$enableval" else $as_nop be_luke="no" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the force is with you" >&5 printf %s "checking whether the force is with you... " >&6; } if test "x$be_luke" = "xyes"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi GETTEXT_PACKAGE=$PACKAGE printf "%s\n" "#define GETTEXT_PACKAGE \"$PACKAGE\"" >>confdefs.h # double eval since datarootdir is usually defined as ${prefix}/share if test -z "$MINGW_TRUE"; then : pkgdatadir='${prefix}/data' else pkgdatadir='${datarootdir}/geany' fi if test -z "$MINGW_TRUE"; then : LIBS="$LIBS -liconv" fi GEANY_DATA_DIR=$(eval echo $(eval echo $pkgdatadir)) # The default Python command. On Windows, use the `py` launcher by default # Check whether --with-python-command was given. if test ${with_python_command+y} then : withval=$with_python_command; with_python_command=$withval else $as_nop with_python_command=auto fi if test "x$with_python_command" = xauto then : if test -z "$MINGW_TRUE"; then : with_python_command=py else with_python_command=python fi fi PYTHON_COMMAND=$with_python_command # Documentation tools if test -f "$srcdir/doc/geany.html" then : have_prebuilt_html_docs=yes else $as_nop have_prebuilt_html_docs=no fi html_docs_default=yes if test "$REVISION" = "-1" && test "x$have_prebuilt_html_docs" = xyes then : html_docs_default=auto fi # Check whether --enable-html-docs was given. if test ${enable_html_docs+y} then : enableval=$enable_html_docs; geany_enable_html_docs="$enableval" else $as_nop geany_enable_html_docs="$html_docs_default" fi if test "x$geany_enable_html_docs" != "xno" then : for ac_prog in rst2html rst2html.py do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_path_RST2HTML+y} then : printf %s "(cached) " >&6 else $as_nop case $RST2HTML in [\\/]* | ?:[\\/]*) ac_cv_path_RST2HTML="$RST2HTML" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_path_RST2HTML="$as_dir$ac_word$ac_exec_ext" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi RST2HTML=$ac_cv_path_RST2HTML if test -n "$RST2HTML"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $RST2HTML" >&5 printf "%s\n" "$RST2HTML" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$RST2HTML" && break done test -n "$RST2HTML" || RST2HTML="no" if test "x$RST2HTML" != "xno" then : geany_enable_html_docs="yes" elif test "x$geany_enable_html_docs" = "xyes" then : as_fn_error $? "Documentation enabled but rst2html not found. You can explicitly disable building of the HTML manual with --disable-html-docs, but you then may not have a local copy of the HTML manual." "$LINENO" 5 else $as_nop geany_enable_html_docs="no" fi fi if test "x$geany_enable_html_docs" != "xno"; then WITH_RST2HTML_TRUE= WITH_RST2HTML_FALSE='#' else WITH_RST2HTML_TRUE='#' WITH_RST2HTML_FALSE= fi if test "x$geany_enable_html_docs" != "xno" || test "x$have_prebuilt_html_docs" = xyes; then INSTALL_HTML_DOCS_TRUE= INSTALL_HTML_DOCS_FALSE='#' else INSTALL_HTML_DOCS_TRUE='#' INSTALL_HTML_DOCS_FALSE= fi _GEANY_STATUS="$_GEANY_STATUS Build HTML documentation:$geany_enable_html_docs" # Check whether --enable-pdf-docs was given. if test ${enable_pdf_docs+y} then : enableval=$enable_pdf_docs; geany_enable_pdf_docs="$enableval" else $as_nop geany_enable_pdf_docs="auto" fi if test "x$geany_enable_pdf_docs" != "xno" then : for ac_prog in rst2pdf rst2pdf.py do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_path_RST2PDF+y} then : printf %s "(cached) " >&6 else $as_nop case $RST2PDF in [\\/]* | ?:[\\/]*) ac_cv_path_RST2PDF="$RST2PDF" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_path_RST2PDF="$as_dir$ac_word$ac_exec_ext" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi RST2PDF=$ac_cv_path_RST2PDF if test -n "$RST2PDF"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $RST2PDF" >&5 printf "%s\n" "$RST2PDF" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$RST2PDF" && break done test -n "$RST2PDF" || RST2PDF="no" if test "x$RST2PDF" != "xno" then : geany_enable_pdf_docs="yes" elif test "x$geany_enable_pdf_docs" = "xyes" then : as_fn_error $? "PDF documentation enabled but rst2pdf not found" "$LINENO" 5 else $as_nop geany_enable_pdf_docs="no" fi fi if test "x$geany_enable_pdf_docs" != "xno"; then WITH_RST2PDF_TRUE= WITH_RST2PDF_FALSE='#' else WITH_RST2PDF_TRUE='#' WITH_RST2PDF_FALSE= fi _GEANY_STATUS="$_GEANY_STATUS Build PDF documentation:$geany_enable_pdf_docs" # Check whether --enable-api-docs was given. if test ${enable_api_docs+y} then : enableval=$enable_api_docs; geany_with_doxygen="$enableval" else $as_nop geany_with_doxygen="auto" fi if test "x$geany_with_doxygen" != "xno" then : # Extract the first word of "doxygen", so it can be a program name with args. set dummy doxygen; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_path_DOXYGEN+y} then : printf %s "(cached) " >&6 else $as_nop case $DOXYGEN in [\\/]* | ?:[\\/]*) ac_cv_path_DOXYGEN="$DOXYGEN" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_path_DOXYGEN="$as_dir$ac_word$ac_exec_ext" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_DOXYGEN" && ac_cv_path_DOXYGEN="no" ;; esac fi DOXYGEN=$ac_cv_path_DOXYGEN if test -n "$DOXYGEN"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $DOXYGEN" >&5 printf "%s\n" "$DOXYGEN" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$DOXYGEN" != "xno" then : geany_with_doxygen=yes elif test "x$geany_with_doxygen" = xyes then : as_fn_error $? "API documentation enabled but doxygen not found" "$LINENO" 5 else $as_nop geany_with_doxygen=no fi fi if test "x$geany_with_doxygen" != "xno"; then WITH_DOXYGEN_TRUE= WITH_DOXYGEN_FALSE='#' else WITH_DOXYGEN_TRUE='#' WITH_DOXYGEN_FALSE= fi _GEANY_STATUS="$_GEANY_STATUS Build API documentation:$geany_with_doxygen" # Check whether --enable-gtkdoc-header was given. if test ${enable_gtkdoc_header+y} then : enableval=$enable_gtkdoc_header; geany_enable_gtkdoc_header="$enableval" else $as_nop geany_enable_gtkdoc_header="auto" fi if test "x$geany_enable_gtkdoc_header$geany_with_doxygen" = "xyesno" then : as_fn_error $? "GtkDoc header generation enabled but Doxygen support not available" "$LINENO" 5 elif test "x$geany_enable_gtkdoc_header" != "xno" then : if test -n "$PYTHON"; then # If the user set $PYTHON, use it and don't search something else. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $PYTHON version is >= 3" >&5 printf %s "checking whether $PYTHON version is >= 3... " >&6; } prog="import sys # split strings by '.' and convert to numeric. Append some zeros # because we need at least 4 digits for the hex conversion. # map returns an iterator in Python 3.0 and a list in 2.x minver = list(map(int, '3'.split('.'))) + [0, 0, 0] minverhex = 0 # xrange is not present in Python 3.0 and range returns an iterator for i in list(range(0, 4)): minverhex = (minverhex << 8) + minver[i] sys.exit(sys.hexversion < minverhex)" if { echo "$as_me:$LINENO: $PYTHON -c "$prog"" >&5 ($PYTHON -c "$prog") >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } as_fn_error $? "Python interpreter is too old" "$LINENO" 5 fi am_display_PYTHON=$PYTHON else # Otherwise, try each interpreter until we find one that satisfies # VERSION. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a Python interpreter with version >= 3" >&5 printf %s "checking for a Python interpreter with version >= 3... " >&6; } if test ${am_cv_pathless_PYTHON+y} then : printf %s "(cached) " >&6 else $as_nop for am_cv_pathless_PYTHON in python python2 python3 python3.11 python3.10 python3.9 python3.8 python3.7 python3.6 python3.5 python3.4 python3.3 python3.2 python3.1 python3.0 python2.7 python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 python2.0 none; do test "$am_cv_pathless_PYTHON" = none && break prog="import sys # split strings by '.' and convert to numeric. Append some zeros # because we need at least 4 digits for the hex conversion. # map returns an iterator in Python 3.0 and a list in 2.x minver = list(map(int, '3'.split('.'))) + [0, 0, 0] minverhex = 0 # xrange is not present in Python 3.0 and range returns an iterator for i in list(range(0, 4)): minverhex = (minverhex << 8) + minver[i] sys.exit(sys.hexversion < minverhex)" if { echo "$as_me:$LINENO: $am_cv_pathless_PYTHON -c "$prog"" >&5 ($am_cv_pathless_PYTHON -c "$prog") >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } then : break fi done fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_pathless_PYTHON" >&5 printf "%s\n" "$am_cv_pathless_PYTHON" >&6; } # Set $PYTHON to the absolute path of $am_cv_pathless_PYTHON. if test "$am_cv_pathless_PYTHON" = none; then PYTHON=: else # Extract the first word of "$am_cv_pathless_PYTHON", so it can be a program name with args. set dummy $am_cv_pathless_PYTHON; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_path_PYTHON+y} then : printf %s "(cached) " >&6 else $as_nop case $PYTHON in [\\/]* | ?:[\\/]*) ac_cv_path_PYTHON="$PYTHON" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_path_PYTHON="$as_dir$ac_word$ac_exec_ext" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi PYTHON=$ac_cv_path_PYTHON if test -n "$PYTHON"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PYTHON" >&5 printf "%s\n" "$PYTHON" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi am_display_PYTHON=$am_cv_pathless_PYTHON fi if test "$PYTHON" = :; then have_python=no else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $am_display_PYTHON version" >&5 printf %s "checking for $am_display_PYTHON version... " >&6; } if test ${am_cv_python_version+y} then : printf %s "(cached) " >&6 else $as_nop am_cv_python_version=`$PYTHON -c "import sys; print ('%u.%u' % sys.version_info[:2])"` fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_version" >&5 printf "%s\n" "$am_cv_python_version" >&6; } PYTHON_VERSION=$am_cv_python_version { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $am_display_PYTHON platform" >&5 printf %s "checking for $am_display_PYTHON platform... " >&6; } if test ${am_cv_python_platform+y} then : printf %s "(cached) " >&6 else $as_nop am_cv_python_platform=`$PYTHON -c "import sys; sys.stdout.write(sys.platform)"` fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_platform" >&5 printf "%s\n" "$am_cv_python_platform" >&6; } PYTHON_PLATFORM=$am_cv_python_platform if test "x$prefix" = xNONE; then am__usable_prefix=$ac_default_prefix else am__usable_prefix=$prefix fi # Allow user to request using sys.* values from Python, # instead of the GNU $prefix values. # Check whether --with-python-sys-prefix was given. if test ${with_python_sys_prefix+y} then : withval=$with_python_sys_prefix; am_use_python_sys=: else $as_nop am_use_python_sys=false fi # Allow user to override whatever the default Python prefix is. # Check whether --with-python_prefix was given. if test ${with_python_prefix+y} then : withval=$with_python_prefix; am_python_prefix_subst=$withval am_cv_python_prefix=$withval { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for explicit $am_display_PYTHON prefix" >&5 printf %s "checking for explicit $am_display_PYTHON prefix... " >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_prefix" >&5 printf "%s\n" "$am_cv_python_prefix" >&6; } else $as_nop if $am_use_python_sys; then # using python sys.prefix value, not GNU { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for python default $am_display_PYTHON prefix" >&5 printf %s "checking for python default $am_display_PYTHON prefix... " >&6; } if test ${am_cv_python_prefix+y} then : printf %s "(cached) " >&6 else $as_nop am_cv_python_prefix=`$PYTHON -c "import sys; sys.stdout.write(sys.prefix)"` fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_prefix" >&5 printf "%s\n" "$am_cv_python_prefix" >&6; } case $am_cv_python_prefix in $am__usable_prefix*) am__strip_prefix=`echo "$am__usable_prefix" | sed 's|.|.|g'` am_python_prefix_subst=`echo "$am_cv_python_prefix" | sed "s,^$am__strip_prefix,\\${prefix},"` ;; *) am_python_prefix_subst=$am_cv_python_prefix ;; esac else # using GNU prefix value, not python sys.prefix am_python_prefix_subst='${prefix}' am_python_prefix=$am_python_prefix_subst { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GNU default $am_display_PYTHON prefix" >&5 printf %s "checking for GNU default $am_display_PYTHON prefix... " >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_python_prefix" >&5 printf "%s\n" "$am_python_prefix" >&6; } fi fi # Substituting python_prefix_subst value. PYTHON_PREFIX=$am_python_prefix_subst # emacs-page Now do it all over again for Python exec_prefix, but with yet # another conditional: fall back to regular prefix if that was specified. # Check whether --with-python_exec_prefix was given. if test ${with_python_exec_prefix+y} then : withval=$with_python_exec_prefix; am_python_exec_prefix_subst=$withval am_cv_python_exec_prefix=$withval { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for explicit $am_display_PYTHON exec_prefix" >&5 printf %s "checking for explicit $am_display_PYTHON exec_prefix... " >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_exec_prefix" >&5 printf "%s\n" "$am_cv_python_exec_prefix" >&6; } else $as_nop # no explicit --with-python_exec_prefix, but if # --with-python_prefix was given, use its value for python_exec_prefix too. if test -n "$with_python_prefix" then : am_python_exec_prefix_subst=$with_python_prefix am_cv_python_exec_prefix=$with_python_prefix { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for python_prefix-given $am_display_PYTHON exec_prefix" >&5 printf %s "checking for python_prefix-given $am_display_PYTHON exec_prefix... " >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_exec_prefix" >&5 printf "%s\n" "$am_cv_python_exec_prefix" >&6; } else $as_nop # Set am__usable_exec_prefix whether using GNU or Python values, # since we use that variable for pyexecdir. if test "x$exec_prefix" = xNONE; then am__usable_exec_prefix=$am__usable_prefix else am__usable_exec_prefix=$exec_prefix fi # if $am_use_python_sys; then # using python sys.exec_prefix, not GNU { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for python default $am_display_PYTHON exec_prefix" >&5 printf %s "checking for python default $am_display_PYTHON exec_prefix... " >&6; } if test ${am_cv_python_exec_prefix+y} then : printf %s "(cached) " >&6 else $as_nop am_cv_python_exec_prefix=`$PYTHON -c "import sys; sys.stdout.write(sys.exec_prefix)"` fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_exec_prefix" >&5 printf "%s\n" "$am_cv_python_exec_prefix" >&6; } case $am_cv_python_exec_prefix in $am__usable_exec_prefix*) am__strip_prefix=`echo "$am__usable_exec_prefix" | sed 's|.|.|g'` am_python_exec_prefix_subst=`echo "$am_cv_python_exec_prefix" | sed "s,^$am__strip_prefix,\\${exec_prefix},"` ;; *) am_python_exec_prefix_subst=$am_cv_python_exec_prefix ;; esac else # using GNU $exec_prefix, not python sys.exec_prefix am_python_exec_prefix_subst='${exec_prefix}' am_python_exec_prefix=$am_python_exec_prefix_subst { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GNU default $am_display_PYTHON exec_prefix" >&5 printf %s "checking for GNU default $am_display_PYTHON exec_prefix... " >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_python_exec_prefix" >&5 printf "%s\n" "$am_python_exec_prefix" >&6; } fi fi fi # Substituting python_exec_prefix_subst. PYTHON_EXEC_PREFIX=$am_python_exec_prefix_subst # Factor out some code duplication into this shell variable. am_python_setup_sysconfig="\ import sys # Prefer sysconfig over distutils.sysconfig, for better compatibility # with python 3.x. See automake bug#10227. try: import sysconfig except ImportError: can_use_sysconfig = 0 else: can_use_sysconfig = 1 # Can't use sysconfig in CPython 2.7, since it's broken in virtualenvs: # try: from platform import python_implementation if python_implementation() == 'CPython' and sys.version[:3] == '2.7': can_use_sysconfig = 0 except ImportError: pass" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $am_display_PYTHON script directory (pythondir)" >&5 printf %s "checking for $am_display_PYTHON script directory (pythondir)... " >&6; } if test ${am_cv_python_pythondir+y} then : printf %s "(cached) " >&6 else $as_nop if test "x$am_cv_python_prefix" = x; then am_py_prefix=$am__usable_prefix else am_py_prefix=$am_cv_python_prefix fi am_cv_python_pythondir=`$PYTHON -c " $am_python_setup_sysconfig if can_use_sysconfig: if hasattr(sysconfig, 'get_default_scheme'): scheme = sysconfig.get_default_scheme() else: scheme = sysconfig._get_default_scheme() if scheme == 'posix_local': # Debian's default scheme installs to /usr/local/ but we want to find headers in /usr/ scheme = 'posix_prefix' sitedir = sysconfig.get_path('purelib', scheme, vars={'base':'$am_py_prefix'}) else: from distutils import sysconfig sitedir = sysconfig.get_python_lib(0, 0, prefix='$am_py_prefix') sys.stdout.write(sitedir)"` # case $am_cv_python_pythondir in $am_py_prefix*) am__strip_prefix=`echo "$am_py_prefix" | sed 's|.|.|g'` am_cv_python_pythondir=`echo "$am_cv_python_pythondir" | sed "s,^$am__strip_prefix,\\${PYTHON_PREFIX},"` ;; *) case $am_py_prefix in /usr|/System*) ;; *) am_cv_python_pythondir="\${PYTHON_PREFIX}/lib/python$PYTHON_VERSION/site-packages" ;; esac ;; esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_pythondir" >&5 printf "%s\n" "$am_cv_python_pythondir" >&6; } pythondir=$am_cv_python_pythondir pkgpythondir=\${pythondir}/$PACKAGE { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $am_display_PYTHON extension module directory (pyexecdir)" >&5 printf %s "checking for $am_display_PYTHON extension module directory (pyexecdir)... " >&6; } if test ${am_cv_python_pyexecdir+y} then : printf %s "(cached) " >&6 else $as_nop if test "x$am_cv_python_exec_prefix" = x; then am_py_exec_prefix=$am__usable_exec_prefix else am_py_exec_prefix=$am_cv_python_exec_prefix fi am_cv_python_pyexecdir=`$PYTHON -c " $am_python_setup_sysconfig if can_use_sysconfig: if hasattr(sysconfig, 'get_default_scheme'): scheme = sysconfig.get_default_scheme() else: scheme = sysconfig._get_default_scheme() if scheme == 'posix_local': # Debian's default scheme installs to /usr/local/ but we want to find headers in /usr/ scheme = 'posix_prefix' sitedir = sysconfig.get_path('platlib', scheme, vars={'platbase':'$am_py_exec_prefix'}) else: from distutils import sysconfig sitedir = sysconfig.get_python_lib(1, 0, prefix='$am_py_exec_prefix') sys.stdout.write(sitedir)"` # case $am_cv_python_pyexecdir in $am_py_exec_prefix*) am__strip_prefix=`echo "$am_py_exec_prefix" | sed 's|.|.|g'` am_cv_python_pyexecdir=`echo "$am_cv_python_pyexecdir" | sed "s,^$am__strip_prefix,\\${PYTHON_EXEC_PREFIX},"` ;; *) case $am_py_exec_prefix in /usr|/System*) ;; *) am_cv_python_pyexecdir="\${PYTHON_EXEC_PREFIX}/lib/python$PYTHON_VERSION/site-packages" ;; esac ;; esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_pyexecdir" >&5 printf "%s\n" "$am_cv_python_pyexecdir" >&6; } pyexecdir=$am_cv_python_pyexecdir pkgpyexecdir=\${pyexecdir}/$PACKAGE have_python=yes fi if test "x$have_python" = xyes then : have_python_and_lxml=yes { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for python lxml package" >&5 printf %s "checking for python lxml package... " >&6; } if $PYTHON -c 'import lxml' >/dev/null 2>&1 then : have_python_and_lxml=yes else $as_nop have_python_and_lxml=no fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_python_and_lxml" >&5 printf "%s\n" "$have_python_and_lxml" >&6; } else $as_nop have_python_and_lxml=no fi if test "x$geany_enable_gtkdoc_header$have_python_and_lxml" = "xyesno" then : as_fn_error $? "GtkDoc header generation enabled but python or its lxml module not found" "$LINENO" 5 else $as_nop geany_enable_gtkdoc_header=$have_python_and_lxml fi fi if test "x$geany_enable_gtkdoc_header" = "xyes"; then ENABLE_GTKDOC_HEADER_TRUE= ENABLE_GTKDOC_HEADER_FALSE='#' else ENABLE_GTKDOC_HEADER_TRUE='#' ENABLE_GTKDOC_HEADER_FALSE= fi _GEANY_STATUS="$_GEANY_STATUS Generate GtkDoc header:$geany_enable_gtkdoc_header" # libgeany have_gcc4_visibility=no { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether compiler supports GCC4-style visibility" >&5 printf %s "checking whether compiler supports GCC4-style visibility... " >&6; } gcc_visibility_backup_cflags=$CFLAGS CFLAGS=-fvisibility=hidden cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ __attribute__((visibility("default"))) int main(int argc, char **argv) { return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : have_gcc4_visibility=yes fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_gcc4_visibility" >&5 printf "%s\n" "$have_gcc4_visibility" >&6; } CFLAGS="${gcc_visibility_backup_cflags}" if test -z "$MINGW_TRUE"; then : win32=yes else win32=false fi export_CFLAGS= if test x$win32 = xyes then : export_CFLAGS='-DGEANY_EXPORT_SYMBOL="__declspec(dllexport)"' elif test x$have_gcc4_visibility = xyes then : export_CFLAGS='-fvisibility=hidden -DGEANY_EXPORT_SYMBOL="__attribute__((visibility(\"default\")))"' else $as_nop export_CFLAGS='-DGEANY_EXPORT_SYMBOL' fi LIBGEANY_EXPORT_CFLAGS="${export_CFLAGS} -DGEANY_API_SYMBOL=GEANY_EXPORT_SYMBOL" libgeany_current=0 libgeany_revision=0 libgeany_age=0 LIBGEANY_CFLAGS="${LIBGEANY_EXPORT_CFLAGS}" LIBGEANY_LDFLAGS="-version-info ${libgeany_current}:${libgeany_revision}:${libgeany_age}" # Extract the first word of "sort", so it can be a program name with args. set dummy sort; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_path_SORT+y} then : printf %s "(cached) " >&6 else $as_nop case $SORT in [\\/]* | ?:[\\/]*) ac_cv_path_SORT="$SORT" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_path_SORT="$as_dir$ac_word$ac_exec_ext" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_SORT" && ac_cv_path_SORT=" as_fn_error $? "The 'sort' utility is required, is it installed?" "$LINENO" 5" ;; esac fi SORT=$ac_cv_path_SORT if test -n "$SORT"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $SORT" >&5 printf "%s\n" "$SORT" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi # Extract the first word of "uniq", so it can be a program name with args. set dummy uniq; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_path_UNIQ+y} then : printf %s "(cached) " >&6 else $as_nop case $UNIQ in [\\/]* | ?:[\\/]*) ac_cv_path_UNIQ="$UNIQ" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_path_UNIQ="$as_dir$ac_word$ac_exec_ext" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_UNIQ" && ac_cv_path_UNIQ=" as_fn_error $? "The 'uniq' utility is required, is it installed?" "$LINENO" 5" ;; esac fi UNIQ=$ac_cv_path_UNIQ if test -n "$UNIQ"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $UNIQ" >&5 printf "%s\n" "$UNIQ" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi # Output ac_config_files="$ac_config_files Makefile icons/Makefile icons/16x16/Makefile icons/24x24/Makefile icons/32x32/Makefile icons/48x48/Makefile icons/scalable/Makefile icons/tango/Makefile icons/tango/16x16/Makefile icons/tango/24x24/Makefile icons/tango/32x32/Makefile icons/tango/48x48/Makefile icons/tango/scalable/Makefile ctags/Makefile scintilla/Makefile src/Makefile src/tagmanager/Makefile plugins/Makefile po/Makefile.in data/Makefile data/filedefs/filetypes.python doc/Makefile doc/geany.1 geany.pc geany.nsi tests/Makefile tests/ctags/Makefile" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test ${\1+y} || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 printf "%s\n" "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else case $cache_file in #( */* | ?:*) mv -f confcache "$cache_file"$$ && mv -f "$cache_file"$$ "$cache_file" ;; #( *) mv -f confcache "$cache_file" ;; esac fi fi else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 printf "%s\n" "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`printf "%s\n" "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 printf %s "checking that generated files are newer than configure... " >&6; } if test -n "$am_sleep_pid"; then # Hide warnings about reused PIDs. wait $am_sleep_pid 2>/dev/null fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: done" >&5 printf "%s\n" "done" >&6; } if test -n "$EXEEXT"; then am__EXEEXT_TRUE= am__EXEEXT_FALSE='#' else am__EXEEXT_TRUE='#' am__EXEEXT_FALSE= fi if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then as_fn_error $? "conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCXX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${USE_BUNDLED_REGEX_TRUE}" && test -z "${USE_BUNDLED_REGEX_FALSE}"; then as_fn_error $? "conditional \"USE_BUNDLED_REGEX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${USE_BUNDLED_FNMATCH_TRUE}" && test -z "${USE_BUNDLED_FNMATCH_FALSE}"; then as_fn_error $? "conditional \"USE_BUNDLED_FNMATCH\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${ENABLE_BINRELOC_TRUE}" && test -z "${ENABLE_BINRELOC_FALSE}"; then as_fn_error $? "conditional \"ENABLE_BINRELOC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${PLUGINS_TRUE}" && test -z "${PLUGINS_FALSE}"; then as_fn_error $? "conditional \"PLUGINS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${PLUGINS_TRUE}" && test -z "${PLUGINS_FALSE}"; then as_fn_error $? "conditional \"PLUGINS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${MINGW_TRUE}" && test -z "${MINGW_FALSE}"; then as_fn_error $? "conditional \"MINGW\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${MINGW_TRUE}" && test -z "${MINGW_FALSE}"; then as_fn_error $? "conditional \"MINGW\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${ENABLE_MAC_INTEGRATION_TRUE}" && test -z "${ENABLE_MAC_INTEGRATION_FALSE}"; then as_fn_error $? "conditional \"ENABLE_MAC_INTEGRATION\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${WITH_RST2HTML_TRUE}" && test -z "${WITH_RST2HTML_FALSE}"; then as_fn_error $? "conditional \"WITH_RST2HTML\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${INSTALL_HTML_DOCS_TRUE}" && test -z "${INSTALL_HTML_DOCS_FALSE}"; then as_fn_error $? "conditional \"INSTALL_HTML_DOCS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${WITH_RST2PDF_TRUE}" && test -z "${WITH_RST2PDF_FALSE}"; then as_fn_error $? "conditional \"WITH_RST2PDF\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${WITH_DOXYGEN_TRUE}" && test -z "${WITH_DOXYGEN_FALSE}"; then as_fn_error $? "conditional \"WITH_DOXYGEN\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${ENABLE_GTKDOC_HEADER_TRUE}" && test -z "${ENABLE_GTKDOC_HEADER_FALSE}"; then as_fn_error $? "conditional \"ENABLE_GTKDOC_HEADER\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 printf "%s\n" "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh as_nop=: if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else $as_nop case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi # Reset variables that may have inherited troublesome values from # the environment. # IFS needs to be set, to space, tab, and newline, in precisely that order. # (If _AS_PATH_WALK were called with IFS unset, it would have the # side effect of setting IFS to empty, thus disabling word splitting.) # Quoting is to prevent editors from complaining about space-tab. as_nl=' ' export as_nl IFS=" "" $as_nl" PS1='$ ' PS2='> ' PS4='+ ' # Ensure predictable behavior from utilities with locale-dependent output. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # We cannot yet rely on "unset" to work, but we need these variables # to be unset--not just set to an empty or harmless value--now, to # avoid bugs in old shells (e.g. pre-3.0 UWIN ksh). This construct # also avoids known problems related to "unset" and subshell syntax # in other old shells (e.g. bash 2.01 and pdksh 5.2.14). for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH do eval test \${$as_var+y} \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done # Ensure that fds 0, 1, and 2 are open. if (exec 3>&0) 2>/dev/null; then :; else exec 0&1) 2>/dev/null; then :; else exec 1>/dev/null; fi if (exec 3>&2) ; then :; else exec 2>/dev/null; fi # The user is always right. if ${PATH_SEPARATOR+false} :; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac test -r "$as_dir$0" && as_myself=$as_dir$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi printf "%s\n" "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null then : eval 'as_fn_append () { eval $1+=\$2 }' else $as_nop as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null then : eval 'as_fn_arith () { as_val=$(( $* )) }' else $as_nop as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits # Determine whether it's possible to make 'echo' print without a newline. # These variables are no longer used directly by Autoconf, but are AC_SUBSTed # for compatibility with existing Makefiles. ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac # For backward compatibility with old third-party macros, we provide # the shell variables $as_echo and $as_echo_n. New code should use # AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively. as_echo='printf %s\n' as_echo_n='printf %s' rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by Geany $as_me 2.0, which was generated by GNU Autoconf 2.71. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac case $ac_config_headers in *" "*) set x $ac_config_headers; shift; ac_config_headers=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" config_headers="$ac_config_headers" config_commands="$ac_config_commands" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Configuration commands: $config_commands Report bugs to ." _ACEOF ac_cs_config=`printf "%s\n" "$ac_configure_args" | sed "$ac_safe_unquote"` ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\''/g"` cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ Geany config.status 2.0 configured by $0, generated by GNU Autoconf 2.71, with options \\"\$ac_cs_config\\" Copyright (C) 2021 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' MKDIR_P='$MKDIR_P' AWK='$AWK' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) printf "%s\n" "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) printf "%s\n" "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`printf "%s\n" "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`printf "%s\n" "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_HEADERS " '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header as_fn_error $? "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) printf "%s\n" "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \printf "%s\n" "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX printf "%s\n" "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # # INIT-COMMANDS # AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}" # Capture the value of obsolete ALL_LINGUAS because we need it to compute # POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES, CATALOGS. But hide it # from automake < 1.5. eval 'OBSOLETE_ALL_LINGUAS''="$ALL_LINGUAS"' # Capture the value of LINGUAS because we need it to compute CATALOGS. LINGUAS="${LINGUAS-%UNSET%}" # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH sed_quote_subst='$sed_quote_subst' double_quote_subst='$double_quote_subst' delay_variable_subst='$delay_variable_subst' macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' shared_archive_member_spec='`$ECHO "$shared_archive_member_spec" | $SED "$delay_single_quote_subst"`' SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`' host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`' lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`' reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' FILECMD='`$ECHO "$FILECMD" | $SED "$delay_single_quote_subst"`' OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`' want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`' DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`' AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' lt_ar_flags='`$ECHO "$lt_ar_flags" | $SED "$delay_single_quote_subst"`' AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`' STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_import='`$ECHO "$lt_cv_sys_global_symbol_to_import" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' lt_cv_nm_interface='`$ECHO "$lt_cv_nm_interface" | $SED "$delay_single_quote_subst"`' nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`' lt_cv_truncate_bin='`$ECHO "$lt_cv_truncate_bin" | $SED "$delay_single_quote_subst"`' objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`' DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`' file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' configure_time_dlsearch_path='`$ECHO "$configure_time_dlsearch_path" | $SED "$delay_single_quote_subst"`' configure_time_lt_sys_library_path='`$ECHO "$configure_time_lt_sys_library_path" | $SED "$delay_single_quote_subst"`' hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' compiler_lib_search_dirs='`$ECHO "$compiler_lib_search_dirs" | $SED "$delay_single_quote_subst"`' predep_objects='`$ECHO "$predep_objects" | $SED "$delay_single_quote_subst"`' postdep_objects='`$ECHO "$postdep_objects" | $SED "$delay_single_quote_subst"`' predeps='`$ECHO "$predeps" | $SED "$delay_single_quote_subst"`' postdeps='`$ECHO "$postdeps" | $SED "$delay_single_quote_subst"`' compiler_lib_search_path='`$ECHO "$compiler_lib_search_path" | $SED "$delay_single_quote_subst"`' LD_CXX='`$ECHO "$LD_CXX" | $SED "$delay_single_quote_subst"`' reload_flag_CXX='`$ECHO "$reload_flag_CXX" | $SED "$delay_single_quote_subst"`' reload_cmds_CXX='`$ECHO "$reload_cmds_CXX" | $SED "$delay_single_quote_subst"`' old_archive_cmds_CXX='`$ECHO "$old_archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' compiler_CXX='`$ECHO "$compiler_CXX" | $SED "$delay_single_quote_subst"`' GCC_CXX='`$ECHO "$GCC_CXX" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_no_builtin_flag_CXX='`$ECHO "$lt_prog_compiler_no_builtin_flag_CXX" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_pic_CXX='`$ECHO "$lt_prog_compiler_pic_CXX" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_wl_CXX='`$ECHO "$lt_prog_compiler_wl_CXX" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_static_CXX='`$ECHO "$lt_prog_compiler_static_CXX" | $SED "$delay_single_quote_subst"`' lt_cv_prog_compiler_c_o_CXX='`$ECHO "$lt_cv_prog_compiler_c_o_CXX" | $SED "$delay_single_quote_subst"`' archive_cmds_need_lc_CXX='`$ECHO "$archive_cmds_need_lc_CXX" | $SED "$delay_single_quote_subst"`' enable_shared_with_static_runtimes_CXX='`$ECHO "$enable_shared_with_static_runtimes_CXX" | $SED "$delay_single_quote_subst"`' export_dynamic_flag_spec_CXX='`$ECHO "$export_dynamic_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' whole_archive_flag_spec_CXX='`$ECHO "$whole_archive_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' compiler_needs_object_CXX='`$ECHO "$compiler_needs_object_CXX" | $SED "$delay_single_quote_subst"`' old_archive_from_new_cmds_CXX='`$ECHO "$old_archive_from_new_cmds_CXX" | $SED "$delay_single_quote_subst"`' old_archive_from_expsyms_cmds_CXX='`$ECHO "$old_archive_from_expsyms_cmds_CXX" | $SED "$delay_single_quote_subst"`' archive_cmds_CXX='`$ECHO "$archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' archive_expsym_cmds_CXX='`$ECHO "$archive_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' module_cmds_CXX='`$ECHO "$module_cmds_CXX" | $SED "$delay_single_quote_subst"`' module_expsym_cmds_CXX='`$ECHO "$module_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' with_gnu_ld_CXX='`$ECHO "$with_gnu_ld_CXX" | $SED "$delay_single_quote_subst"`' allow_undefined_flag_CXX='`$ECHO "$allow_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' no_undefined_flag_CXX='`$ECHO "$no_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' hardcode_libdir_flag_spec_CXX='`$ECHO "$hardcode_libdir_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' hardcode_libdir_separator_CXX='`$ECHO "$hardcode_libdir_separator_CXX" | $SED "$delay_single_quote_subst"`' hardcode_direct_CXX='`$ECHO "$hardcode_direct_CXX" | $SED "$delay_single_quote_subst"`' hardcode_direct_absolute_CXX='`$ECHO "$hardcode_direct_absolute_CXX" | $SED "$delay_single_quote_subst"`' hardcode_minus_L_CXX='`$ECHO "$hardcode_minus_L_CXX" | $SED "$delay_single_quote_subst"`' hardcode_shlibpath_var_CXX='`$ECHO "$hardcode_shlibpath_var_CXX" | $SED "$delay_single_quote_subst"`' hardcode_automatic_CXX='`$ECHO "$hardcode_automatic_CXX" | $SED "$delay_single_quote_subst"`' inherit_rpath_CXX='`$ECHO "$inherit_rpath_CXX" | $SED "$delay_single_quote_subst"`' link_all_deplibs_CXX='`$ECHO "$link_all_deplibs_CXX" | $SED "$delay_single_quote_subst"`' always_export_symbols_CXX='`$ECHO "$always_export_symbols_CXX" | $SED "$delay_single_quote_subst"`' export_symbols_cmds_CXX='`$ECHO "$export_symbols_cmds_CXX" | $SED "$delay_single_quote_subst"`' exclude_expsyms_CXX='`$ECHO "$exclude_expsyms_CXX" | $SED "$delay_single_quote_subst"`' include_expsyms_CXX='`$ECHO "$include_expsyms_CXX" | $SED "$delay_single_quote_subst"`' prelink_cmds_CXX='`$ECHO "$prelink_cmds_CXX" | $SED "$delay_single_quote_subst"`' postlink_cmds_CXX='`$ECHO "$postlink_cmds_CXX" | $SED "$delay_single_quote_subst"`' file_list_spec_CXX='`$ECHO "$file_list_spec_CXX" | $SED "$delay_single_quote_subst"`' hardcode_action_CXX='`$ECHO "$hardcode_action_CXX" | $SED "$delay_single_quote_subst"`' compiler_lib_search_dirs_CXX='`$ECHO "$compiler_lib_search_dirs_CXX" | $SED "$delay_single_quote_subst"`' predep_objects_CXX='`$ECHO "$predep_objects_CXX" | $SED "$delay_single_quote_subst"`' postdep_objects_CXX='`$ECHO "$postdep_objects_CXX" | $SED "$delay_single_quote_subst"`' predeps_CXX='`$ECHO "$predeps_CXX" | $SED "$delay_single_quote_subst"`' postdeps_CXX='`$ECHO "$postdeps_CXX" | $SED "$delay_single_quote_subst"`' compiler_lib_search_path_CXX='`$ECHO "$compiler_lib_search_path_CXX" | $SED "$delay_single_quote_subst"`' LTCC='$LTCC' LTCFLAGS='$LTCFLAGS' compiler='$compiler_DEFAULT' # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$1 _LTECHO_EOF' } # Quote evaled strings. for var in SHELL \ ECHO \ PATH_SEPARATOR \ SED \ GREP \ EGREP \ FGREP \ LD \ NM \ LN_S \ lt_SP2NL \ lt_NL2SP \ reload_flag \ FILECMD \ OBJDUMP \ deplibs_check_method \ file_magic_cmd \ file_magic_glob \ want_nocaseglob \ DLLTOOL \ sharedlib_from_linklib_cmd \ AR \ archiver_list_spec \ STRIP \ RANLIB \ CC \ CFLAGS \ compiler \ lt_cv_sys_global_symbol_pipe \ lt_cv_sys_global_symbol_to_cdecl \ lt_cv_sys_global_symbol_to_import \ lt_cv_sys_global_symbol_to_c_name_address \ lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ lt_cv_nm_interface \ nm_file_list_spec \ lt_cv_truncate_bin \ lt_prog_compiler_no_builtin_flag \ lt_prog_compiler_pic \ lt_prog_compiler_wl \ lt_prog_compiler_static \ lt_cv_prog_compiler_c_o \ need_locks \ MANIFEST_TOOL \ DSYMUTIL \ NMEDIT \ LIPO \ OTOOL \ OTOOL64 \ shrext_cmds \ export_dynamic_flag_spec \ whole_archive_flag_spec \ compiler_needs_object \ with_gnu_ld \ allow_undefined_flag \ no_undefined_flag \ hardcode_libdir_flag_spec \ hardcode_libdir_separator \ exclude_expsyms \ include_expsyms \ file_list_spec \ variables_saved_for_relink \ libname_spec \ library_names_spec \ soname_spec \ install_override_mode \ finish_eval \ old_striplib \ striplib \ compiler_lib_search_dirs \ predep_objects \ postdep_objects \ predeps \ postdeps \ compiler_lib_search_path \ LD_CXX \ reload_flag_CXX \ compiler_CXX \ lt_prog_compiler_no_builtin_flag_CXX \ lt_prog_compiler_pic_CXX \ lt_prog_compiler_wl_CXX \ lt_prog_compiler_static_CXX \ lt_cv_prog_compiler_c_o_CXX \ export_dynamic_flag_spec_CXX \ whole_archive_flag_spec_CXX \ compiler_needs_object_CXX \ with_gnu_ld_CXX \ allow_undefined_flag_CXX \ no_undefined_flag_CXX \ hardcode_libdir_flag_spec_CXX \ hardcode_libdir_separator_CXX \ exclude_expsyms_CXX \ include_expsyms_CXX \ file_list_spec_CXX \ compiler_lib_search_dirs_CXX \ predep_objects_CXX \ postdep_objects_CXX \ predeps_CXX \ postdeps_CXX \ compiler_lib_search_path_CXX; do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[\\\\\\\`\\"\\\$]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Double-quote double-evaled strings. for var in reload_cmds \ old_postinstall_cmds \ old_postuninstall_cmds \ old_archive_cmds \ extract_expsyms_cmds \ old_archive_from_new_cmds \ old_archive_from_expsyms_cmds \ archive_cmds \ archive_expsym_cmds \ module_cmds \ module_expsym_cmds \ export_symbols_cmds \ prelink_cmds \ postlink_cmds \ postinstall_cmds \ postuninstall_cmds \ finish_cmds \ sys_lib_search_path_spec \ configure_time_dlsearch_path \ configure_time_lt_sys_library_path \ reload_cmds_CXX \ old_archive_cmds_CXX \ old_archive_from_new_cmds_CXX \ old_archive_from_expsyms_cmds_CXX \ archive_cmds_CXX \ archive_expsym_cmds_CXX \ module_cmds_CXX \ module_expsym_cmds_CXX \ export_symbols_cmds_CXX \ prelink_cmds_CXX \ postlink_cmds_CXX; do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[\\\\\\\`\\"\\\$]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done ac_aux_dir='$ac_aux_dir' # See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes INIT. if test -n "\${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi PACKAGE='$PACKAGE' VERSION='$VERSION' RM='$RM' ofile='$ofile' _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; "po-directories") CONFIG_COMMANDS="$CONFIG_COMMANDS po-directories" ;; "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "icons/Makefile") CONFIG_FILES="$CONFIG_FILES icons/Makefile" ;; "icons/16x16/Makefile") CONFIG_FILES="$CONFIG_FILES icons/16x16/Makefile" ;; "icons/24x24/Makefile") CONFIG_FILES="$CONFIG_FILES icons/24x24/Makefile" ;; "icons/32x32/Makefile") CONFIG_FILES="$CONFIG_FILES icons/32x32/Makefile" ;; "icons/48x48/Makefile") CONFIG_FILES="$CONFIG_FILES icons/48x48/Makefile" ;; "icons/scalable/Makefile") CONFIG_FILES="$CONFIG_FILES icons/scalable/Makefile" ;; "icons/tango/Makefile") CONFIG_FILES="$CONFIG_FILES icons/tango/Makefile" ;; "icons/tango/16x16/Makefile") CONFIG_FILES="$CONFIG_FILES icons/tango/16x16/Makefile" ;; "icons/tango/24x24/Makefile") CONFIG_FILES="$CONFIG_FILES icons/tango/24x24/Makefile" ;; "icons/tango/32x32/Makefile") CONFIG_FILES="$CONFIG_FILES icons/tango/32x32/Makefile" ;; "icons/tango/48x48/Makefile") CONFIG_FILES="$CONFIG_FILES icons/tango/48x48/Makefile" ;; "icons/tango/scalable/Makefile") CONFIG_FILES="$CONFIG_FILES icons/tango/scalable/Makefile" ;; "ctags/Makefile") CONFIG_FILES="$CONFIG_FILES ctags/Makefile" ;; "scintilla/Makefile") CONFIG_FILES="$CONFIG_FILES scintilla/Makefile" ;; "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; "src/tagmanager/Makefile") CONFIG_FILES="$CONFIG_FILES src/tagmanager/Makefile" ;; "plugins/Makefile") CONFIG_FILES="$CONFIG_FILES plugins/Makefile" ;; "po/Makefile.in") CONFIG_FILES="$CONFIG_FILES po/Makefile.in" ;; "data/Makefile") CONFIG_FILES="$CONFIG_FILES data/Makefile" ;; "data/filedefs/filetypes.python") CONFIG_FILES="$CONFIG_FILES data/filedefs/filetypes.python" ;; "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; "doc/geany.1") CONFIG_FILES="$CONFIG_FILES doc/geany.1" ;; "geany.pc") CONFIG_FILES="$CONFIG_FILES geany.pc" ;; "geany.nsi") CONFIG_FILES="$CONFIG_FILES geany.nsi" ;; "tests/Makefile") CONFIG_FILES="$CONFIG_FILES tests/Makefile" ;; "tests/ctags/Makefile") CONFIG_FILES="$CONFIG_FILES tests/ctags/Makefile" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test ${CONFIG_FILES+y} || CONFIG_FILES=$config_files test ${CONFIG_HEADERS+y} || CONFIG_HEADERS=$config_headers test ${CONFIG_COMMANDS+y} || CONFIG_COMMANDS=$config_commands fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" # Set up the scripts for CONFIG_HEADERS section. # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then cat >"$ac_tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF # Transform confdefs.h into an awk script `defines.awk', embedded as # here-document in config.status, that substitutes the proper values into # config.h.in to produce config.h. # Create a delimiter string that does not exist in confdefs.h, to ease # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do ac_tt=`sed -n "/$ac_delim/p" confdefs.h` if test -z "$ac_tt"; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done # For the awk script, D is an array of macro values keyed by name, # likewise P contains macro parameters if any. Preserve backslash # newline sequences. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* sed -n ' s/.\{148\}/&'"$ac_delim"'/g t rset :rset s/^[ ]*#[ ]*define[ ][ ]*/ / t def d :def s/\\$// t bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3"/p s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p d :bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3\\\\\\n"\\/p t cont s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p t cont d :cont n s/.\{148\}/&'"$ac_delim"'/g t clear :clear s/\\$// t bsnlc s/["\\]/\\&/g; s/^/"/; s/$/"/p d :bsnlc s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p b cont ' >$CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 for (key in D) D_is_set[key] = 1 FS = "" } /^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { line = \$ 0 split(line, arg, " ") if (arg[1] == "#") { defundef = arg[2] mac1 = arg[3] } else { defundef = substr(arg[1], 2) mac1 = arg[2] } split(mac1, mac2, "(") #) macro = mac2[1] prefix = substr(line, 1, index(line, defundef) - 1) if (D_is_set[macro]) { # Preserve the white space surrounding the "#". print prefix "define", macro P[macro] D[macro] next } else { # Replace #undef with comments. This is necessary, for example, # in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. if (defundef == "undef") { print "/*", prefix defundef, macro, "*/" next } } } { print } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`printf "%s\n" "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` printf "%s\n" "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 printf "%s\n" "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`printf "%s\n" "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac ac_MKDIR_P=$MKDIR_P case $MKDIR_P in [\\/$]* | ?:[\\/]* ) ;; */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 printf "%s\n" "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t s&@MKDIR_P@&$ac_MKDIR_P&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 printf "%s\n" "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" case $ac_file in -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; :H) # # CONFIG_HEADER # if test x"$ac_file" != x-; then { printf "%s\n" "/* $configure_input */" >&1 \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" } >"$ac_tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 printf "%s\n" "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$ac_tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else printf "%s\n" "/* $configure_input */" >&1 \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi # Compute "$ac_file"'s index in $config_headers. _am_arg="$ac_file" _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || $as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$_am_arg" : 'X\(//\)[^/]' \| \ X"$_am_arg" : 'X\(//\)$' \| \ X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X"$_am_arg" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'`/stamp-h$_am_stamp_count ;; :C) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 printf "%s\n" "$as_me: executing $ac_file commands" >&6;} ;; esac case $ac_file$ac_mode in "depfiles":C) test x"$AMDEP_TRUE" != x"" || { # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. # TODO: see whether this extra hack can be removed once we start # requiring Autoconf 2.70 or later. case $CONFIG_FILES in #( *\'*) : eval set x "$CONFIG_FILES" ;; #( *) : set x $CONFIG_FILES ;; #( *) : ;; esac shift # Used to flag and report bootstrapping failures. am_rc=0 for am_mf do # Strip MF so we end up with the name of the file. am_mf=`printf "%s\n" "$am_mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile which includes # dependency-tracking related rules and includes. # Grep'ing the whole file directly is not great: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \ || continue am_dirpart=`$as_dirname -- "$am_mf" || $as_expr X"$am_mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$am_mf" : 'X\(//\)[^/]' \| \ X"$am_mf" : 'X\(//\)$' \| \ X"$am_mf" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X"$am_mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` am_filepart=`$as_basename -- "$am_mf" || $as_expr X/"$am_mf" : '.*/\([^/][^/]*\)/*$' \| \ X"$am_mf" : 'X\(//\)$' \| \ X"$am_mf" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X/"$am_mf" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` { echo "$as_me:$LINENO: cd "$am_dirpart" \ && sed -e '/# am--include-marker/d' "$am_filepart" \ | $MAKE -f - am--depfiles" >&5 (cd "$am_dirpart" \ && sed -e '/# am--include-marker/d' "$am_filepart" \ | $MAKE -f - am--depfiles) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } || am_rc=$? done if test $am_rc -ne 0; then { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "Something went wrong bootstrapping makefile fragments for automatic dependency tracking. If GNU make was not used, consider re-running the configure script with MAKE=\"gmake\" (or whatever is necessary). You can also try re-running configure with the '--disable-dependency-tracking' option to at least be able to build the package (albeit without support for automatic dependency tracking). See \`config.log' for more details" "$LINENO" 5; } fi { am_dirpart=; unset am_dirpart;} { am_filepart=; unset am_filepart;} { am_mf=; unset am_mf;} { am_rc=; unset am_rc;} rm -f conftest-deps.mk } ;; "po-directories":C) for ac_file in $CONFIG_FILES; do # Support "outfile[:infile[:infile...]]" case "$ac_file" in *:*) ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; esac # PO directories have a Makefile.in generated from Makefile.in.in. case "$ac_file" in */Makefile.in) # Adjust a relative srcdir. ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'` ac_dir_suffix=/`echo "$ac_dir"|sed 's%^\./%%'` ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'` # In autoconf-2.13 it is called $ac_given_srcdir. # In autoconf-2.50 it is called $srcdir. test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir" case "$ac_given_srcdir" in .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;; /*) top_srcdir="$ac_given_srcdir" ;; *) top_srcdir="$ac_dots$ac_given_srcdir" ;; esac # Treat a directory as a PO directory if and only if it has a # POTFILES.in file. This allows packages to have multiple PO # directories under different names or in different locations. if test -f "$ac_given_srcdir/$ac_dir/POTFILES.in"; then rm -f "$ac_dir/POTFILES" test -n "$as_me" && echo "$as_me: creating $ac_dir/POTFILES" || echo "creating $ac_dir/POTFILES" gt_tab=`printf '\t'` cat "$ac_given_srcdir/$ac_dir/POTFILES.in" | sed -e "/^#/d" -e "/^[ ${gt_tab}]*\$/d" -e "s,.*, $top_srcdir/& \\\\," | sed -e "\$s/\(.*\) \\\\/\1/" > "$ac_dir/POTFILES" POMAKEFILEDEPS="POTFILES.in" # ALL_LINGUAS, POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES depend # on $ac_dir but don't depend on user-specified configuration # parameters. if test -f "$ac_given_srcdir/$ac_dir/LINGUAS"; then # The LINGUAS file contains the set of available languages. if test -n "$OBSOLETE_ALL_LINGUAS"; then test -n "$as_me" && echo "$as_me: setting ALL_LINGUAS in configure.in is obsolete" || echo "setting ALL_LINGUAS in configure.in is obsolete" fi ALL_LINGUAS_=`sed -e "/^#/d" -e "s/#.*//" "$ac_given_srcdir/$ac_dir/LINGUAS"` # Hide the ALL_LINGUAS assignment from automake < 1.5. eval 'ALL_LINGUAS''=$ALL_LINGUAS_' POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS" else # The set of available languages was given in configure.in. # Hide the ALL_LINGUAS assignment from automake < 1.5. eval 'ALL_LINGUAS''=$OBSOLETE_ALL_LINGUAS' fi # Compute POFILES # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).po) # Compute UPDATEPOFILES # as $(foreach lang, $(ALL_LINGUAS), $(lang).po-update) # Compute DUMMYPOFILES # as $(foreach lang, $(ALL_LINGUAS), $(lang).nop) # Compute GMOFILES # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).gmo) case "$ac_given_srcdir" in .) srcdirpre= ;; *) srcdirpre='$(srcdir)/' ;; esac POFILES= UPDATEPOFILES= DUMMYPOFILES= GMOFILES= for lang in $ALL_LINGUAS; do POFILES="$POFILES $srcdirpre$lang.po" UPDATEPOFILES="$UPDATEPOFILES $lang.po-update" DUMMYPOFILES="$DUMMYPOFILES $lang.nop" GMOFILES="$GMOFILES $srcdirpre$lang.gmo" done # CATALOGS depends on both $ac_dir and the user's LINGUAS # environment variable. INST_LINGUAS= if test -n "$ALL_LINGUAS"; then for presentlang in $ALL_LINGUAS; do useit=no if test "%UNSET%" != "$LINGUAS"; then desiredlanguages="$LINGUAS" else desiredlanguages="$ALL_LINGUAS" fi for desiredlang in $desiredlanguages; do # Use the presentlang catalog if desiredlang is # a. equal to presentlang, or # b. a variant of presentlang (because in this case, # presentlang can be used as a fallback for messages # which are not translated in the desiredlang catalog). case "$desiredlang" in "$presentlang"*) useit=yes;; esac done if test $useit = yes; then INST_LINGUAS="$INST_LINGUAS $presentlang" fi done fi CATALOGS= if test -n "$INST_LINGUAS"; then for lang in $INST_LINGUAS; do CATALOGS="$CATALOGS $lang.gmo" done fi test -n "$as_me" && echo "$as_me: creating $ac_dir/Makefile" || echo "creating $ac_dir/Makefile" sed -e "/^POTFILES =/r $ac_dir/POTFILES" -e "/^# Makevars/r $ac_given_srcdir/$ac_dir/Makevars" -e "s|@POFILES@|$POFILES|g" -e "s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e "s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e "s|@CATALOGS@|$CATALOGS|g" -e "s|@POMAKEFILEDEPS@|$POMAKEFILEDEPS|g" "$ac_dir/Makefile.in" > "$ac_dir/Makefile" for f in "$ac_given_srcdir/$ac_dir"/Rules-*; do if test -f "$f"; then case "$f" in *.orig | *.bak | *~) ;; *) cat "$f" >> "$ac_dir/Makefile" ;; esac fi done fi ;; esac done ;; "libtool":C) # See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes. if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi cfgfile=${ofile}T trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" cat <<_LT_EOF >> "$cfgfile" #! $SHELL # Generated automatically by $as_me ($PACKAGE) $VERSION # NOTE: Changes made to this file will be lost: look at ltmain.sh. # Provide generalized library-building support services. # Written by Gordon Matzigkeit, 1996 # Copyright (C) 2014 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # GNU Libtool 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; either version 2 of of the License, or # (at your option) any later version. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program or library that is built # using GNU Libtool, you may include this file under the same # distribution terms that you use for the rest of that program. # # GNU Libtool 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 . # The names of the tagged configurations supported by this script. available_tags='CXX ' # Configured defaults for sys_lib_dlsearch_path munging. : \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"} # ### BEGIN LIBTOOL CONFIG # Which release of libtool.m4 was used? macro_version=$macro_version macro_revision=$macro_revision # Whether or not to build static libraries. build_old_libs=$enable_static # Whether or not to build shared libraries. build_libtool_libs=$enable_shared # What type of objects to build. pic_mode=$pic_mode # Whether or not to optimize for fast installation. fast_install=$enable_fast_install # Shared archive member basename,for filename based shared library versioning on AIX. shared_archive_member_spec=$shared_archive_member_spec # Shell to use when invoking shell scripts. SHELL=$lt_SHELL # An echo program that protects backslashes. ECHO=$lt_ECHO # The PATH separator for the build system. PATH_SEPARATOR=$lt_PATH_SEPARATOR # The host system. host_alias=$host_alias host=$host host_os=$host_os # The build system. build_alias=$build_alias build=$build build_os=$build_os # A sed program that does not truncate output. SED=$lt_SED # Sed that helps us avoid accidentally triggering echo(1) options like -n. Xsed="\$SED -e 1s/^X//" # A grep program that handles long lines. GREP=$lt_GREP # An ERE matcher. EGREP=$lt_EGREP # A literal string matcher. FGREP=$lt_FGREP # A BSD- or MS-compatible name lister. NM=$lt_NM # Whether we need soft or hard links. LN_S=$lt_LN_S # What is the maximum length of a command? max_cmd_len=$max_cmd_len # Object file suffix (normally "o"). objext=$ac_objext # Executable file suffix (normally ""). exeext=$exeext # whether the shell understands "unset". lt_unset=$lt_unset # turn spaces into newlines. SP2NL=$lt_lt_SP2NL # turn newlines into spaces. NL2SP=$lt_lt_NL2SP # convert \$build file names to \$host format. to_host_file_cmd=$lt_cv_to_host_file_cmd # convert \$build files to toolchain format. to_tool_file_cmd=$lt_cv_to_tool_file_cmd # A file(cmd) program that detects file types. FILECMD=$lt_FILECMD # An object symbol dumper. OBJDUMP=$lt_OBJDUMP # Method to check whether dependent libraries are shared objects. deplibs_check_method=$lt_deplibs_check_method # Command to use when deplibs_check_method = "file_magic". file_magic_cmd=$lt_file_magic_cmd # How to find potential files when deplibs_check_method = "file_magic". file_magic_glob=$lt_file_magic_glob # Find potential files using nocaseglob when deplibs_check_method = "file_magic". want_nocaseglob=$lt_want_nocaseglob # DLL creation program. DLLTOOL=$lt_DLLTOOL # Command to associate shared and link libraries. sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd # The archiver. AR=$lt_AR # Flags to create an archive (by configure). lt_ar_flags=$lt_ar_flags # Flags to create an archive. AR_FLAGS=\${ARFLAGS-"\$lt_ar_flags"} # How to feed a file listing to the archiver. archiver_list_spec=$lt_archiver_list_spec # A symbol stripping program. STRIP=$lt_STRIP # Commands used to install an old-style archive. RANLIB=$lt_RANLIB old_postinstall_cmds=$lt_old_postinstall_cmds old_postuninstall_cmds=$lt_old_postuninstall_cmds # Whether to use a lock for old archive extraction. lock_old_archive_extraction=$lock_old_archive_extraction # A C compiler. LTCC=$lt_CC # LTCC compiler flags. LTCFLAGS=$lt_CFLAGS # Take the output of nm and produce a listing of raw symbols and C names. global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe # Transform the output of nm in a proper C declaration. global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl # Transform the output of nm into a list of symbols to manually relocate. global_symbol_to_import=$lt_lt_cv_sys_global_symbol_to_import # Transform the output of nm in a C name address pair. global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address # Transform the output of nm in a C name address pair when lib prefix is needed. global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix # The name lister interface. nm_interface=$lt_lt_cv_nm_interface # Specify filename containing input files for \$NM. nm_file_list_spec=$lt_nm_file_list_spec # The root where to search for dependent libraries,and where our libraries should be installed. lt_sysroot=$lt_sysroot # Command to truncate a binary pipe. lt_truncate_bin=$lt_lt_cv_truncate_bin # The name of the directory that contains temporary libtool files. objdir=$objdir # Used to examine libraries when file_magic_cmd begins with "file". MAGIC_CMD=$MAGIC_CMD # Must we lock files when doing compilation? need_locks=$lt_need_locks # Manifest tool. MANIFEST_TOOL=$lt_MANIFEST_TOOL # Tool to manipulate archived DWARF debug symbol files on Mac OS X. DSYMUTIL=$lt_DSYMUTIL # Tool to change global to local symbols on Mac OS X. NMEDIT=$lt_NMEDIT # Tool to manipulate fat objects and archives on Mac OS X. LIPO=$lt_LIPO # ldd/readelf like tool for Mach-O binaries on Mac OS X. OTOOL=$lt_OTOOL # ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. OTOOL64=$lt_OTOOL64 # Old archive suffix (normally "a"). libext=$libext # Shared library suffix (normally ".so"). shrext_cmds=$lt_shrext_cmds # The commands to extract the exported symbol list from a shared archive. extract_expsyms_cmds=$lt_extract_expsyms_cmds # Variables whose values should be saved in libtool wrapper scripts and # restored at link time. variables_saved_for_relink=$lt_variables_saved_for_relink # Do we need the "lib" prefix for modules? need_lib_prefix=$need_lib_prefix # Do we need a version for libraries? need_version=$need_version # Library versioning type. version_type=$version_type # Shared library runtime path variable. runpath_var=$runpath_var # Shared library path variable. shlibpath_var=$shlibpath_var # Is shlibpath searched before the hard-coded library search path? shlibpath_overrides_runpath=$shlibpath_overrides_runpath # Format of library name prefix. libname_spec=$lt_libname_spec # List of archive names. First name is the real one, the rest are links. # The last name is the one that the linker finds with -lNAME library_names_spec=$lt_library_names_spec # The coded name of the library, if different from the real name. soname_spec=$lt_soname_spec # Permission mode override for installation of shared libraries. install_override_mode=$lt_install_override_mode # Command to use after installation of a shared archive. postinstall_cmds=$lt_postinstall_cmds # Command to use after uninstallation of a shared archive. postuninstall_cmds=$lt_postuninstall_cmds # Commands used to finish a libtool library installation in a directory. finish_cmds=$lt_finish_cmds # As "finish_cmds", except a single script fragment to be evaled but # not shown. finish_eval=$lt_finish_eval # Whether we should hardcode library paths into libraries. hardcode_into_libs=$hardcode_into_libs # Compile-time system search path for libraries. sys_lib_search_path_spec=$lt_sys_lib_search_path_spec # Detected run-time system search path for libraries. sys_lib_dlsearch_path_spec=$lt_configure_time_dlsearch_path # Explicit LT_SYS_LIBRARY_PATH set during ./configure time. configure_time_lt_sys_library_path=$lt_configure_time_lt_sys_library_path # Whether dlopen is supported. dlopen_support=$enable_dlopen # Whether dlopen of programs is supported. dlopen_self=$enable_dlopen_self # Whether dlopen of statically linked programs is supported. dlopen_self_static=$enable_dlopen_self_static # Commands to strip libraries. old_striplib=$lt_old_striplib striplib=$lt_striplib # The linker used to build libraries. LD=$lt_LD # How to create reloadable object files. reload_flag=$lt_reload_flag reload_cmds=$lt_reload_cmds # Commands used to build an old-style archive. old_archive_cmds=$lt_old_archive_cmds # A language specific compiler. CC=$lt_compiler # Is the compiler the GNU compiler? with_gcc=$GCC # Compiler flag to turn off builtin functions. no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag # Additional compiler flags for building library objects. pic_flag=$lt_lt_prog_compiler_pic # How to pass a linker flag through the compiler. wl=$lt_lt_prog_compiler_wl # Compiler flag to prevent dynamic linking. link_static_flag=$lt_lt_prog_compiler_static # Does compiler simultaneously support -c and -o options? compiler_c_o=$lt_lt_cv_prog_compiler_c_o # Whether or not to add -lc for building shared libraries. build_libtool_need_lc=$archive_cmds_need_lc # Whether or not to disallow shared libs when runtime libs are static. allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes # Compiler flag to allow reflexive dlopens. export_dynamic_flag_spec=$lt_export_dynamic_flag_spec # Compiler flag to generate shared objects directly from archives. whole_archive_flag_spec=$lt_whole_archive_flag_spec # Whether the compiler copes with passing no objects directly. compiler_needs_object=$lt_compiler_needs_object # Create an old-style archive from a shared archive. old_archive_from_new_cmds=$lt_old_archive_from_new_cmds # Create a temporary old-style archive to link instead of a shared archive. old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds # Commands used to build a shared archive. archive_cmds=$lt_archive_cmds archive_expsym_cmds=$lt_archive_expsym_cmds # Commands used to build a loadable module if different from building # a shared archive. module_cmds=$lt_module_cmds module_expsym_cmds=$lt_module_expsym_cmds # Whether we are building with GNU ld or not. with_gnu_ld=$lt_with_gnu_ld # Flag that allows shared libraries with undefined symbols to be built. allow_undefined_flag=$lt_allow_undefined_flag # Flag that enforces no undefined symbols. no_undefined_flag=$lt_no_undefined_flag # Flag to hardcode \$libdir into a binary during linking. # This must work even if \$libdir does not exist hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec # Whether we need a single "-rpath" flag with a separated argument. hardcode_libdir_separator=$lt_hardcode_libdir_separator # Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes # DIR into the resulting binary. hardcode_direct=$hardcode_direct # Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes # DIR into the resulting binary and the resulting library dependency is # "absolute",i.e impossible to change by setting \$shlibpath_var if the # library is relocated. hardcode_direct_absolute=$hardcode_direct_absolute # Set to "yes" if using the -LDIR flag during linking hardcodes DIR # into the resulting binary. hardcode_minus_L=$hardcode_minus_L # Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR # into the resulting binary. hardcode_shlibpath_var=$hardcode_shlibpath_var # Set to "yes" if building a shared library automatically hardcodes DIR # into the library and all subsequent libraries and executables linked # against it. hardcode_automatic=$hardcode_automatic # Set to yes if linker adds runtime paths of dependent libraries # to runtime path list. inherit_rpath=$inherit_rpath # Whether libtool must link a program against all its dependency libraries. link_all_deplibs=$link_all_deplibs # Set to "yes" if exported symbols are required. always_export_symbols=$always_export_symbols # The commands to list exported symbols. export_symbols_cmds=$lt_export_symbols_cmds # Symbols that should not be listed in the preloaded symbols. exclude_expsyms=$lt_exclude_expsyms # Symbols that must always be exported. include_expsyms=$lt_include_expsyms # Commands necessary for linking programs (against libraries) with templates. prelink_cmds=$lt_prelink_cmds # Commands necessary for finishing linking programs. postlink_cmds=$lt_postlink_cmds # Specify filename containing input files. file_list_spec=$lt_file_list_spec # How to hardcode a shared library path into an executable. hardcode_action=$hardcode_action # The directories searched by this compiler when creating a shared library. compiler_lib_search_dirs=$lt_compiler_lib_search_dirs # Dependencies to place before and after the objects being linked to # create a shared library. predep_objects=$lt_predep_objects postdep_objects=$lt_postdep_objects predeps=$lt_predeps postdeps=$lt_postdeps # The library search path used internally by the compiler when linking # a shared library. compiler_lib_search_path=$lt_compiler_lib_search_path # ### END LIBTOOL CONFIG _LT_EOF cat <<'_LT_EOF' >> "$cfgfile" # ### BEGIN FUNCTIONS SHARED WITH CONFIGURE # func_munge_path_list VARIABLE PATH # ----------------------------------- # VARIABLE is name of variable containing _space_ separated list of # directories to be munged by the contents of PATH, which is string # having a format: # "DIR[:DIR]:" # string "DIR[ DIR]" will be prepended to VARIABLE # ":DIR[:DIR]" # string "DIR[ DIR]" will be appended to VARIABLE # "DIRP[:DIRP]::[DIRA:]DIRA" # string "DIRP[ DIRP]" will be prepended to VARIABLE and string # "DIRA[ DIRA]" will be appended to VARIABLE # "DIR[:DIR]" # VARIABLE will be replaced by "DIR[ DIR]" func_munge_path_list () { case x$2 in x) ;; *:) eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\" ;; x:*) eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\" ;; *::*) eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\" ;; *) eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\" ;; esac } # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. func_cc_basename () { for cc_temp in $*""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` } # ### END FUNCTIONS SHARED WITH CONFIGURE _LT_EOF case $host_os in aix3*) cat <<\_LT_EOF >> "$cfgfile" # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi _LT_EOF ;; esac ltmain=$ac_aux_dir/ltmain.sh # We use sed instead of cat because bash on DJGPP gets confused if # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? $SED '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" cat <<_LT_EOF >> "$ofile" # ### BEGIN LIBTOOL TAG CONFIG: CXX # The linker used to build libraries. LD=$lt_LD_CXX # How to create reloadable object files. reload_flag=$lt_reload_flag_CXX reload_cmds=$lt_reload_cmds_CXX # Commands used to build an old-style archive. old_archive_cmds=$lt_old_archive_cmds_CXX # A language specific compiler. CC=$lt_compiler_CXX # Is the compiler the GNU compiler? with_gcc=$GCC_CXX # Compiler flag to turn off builtin functions. no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX # Additional compiler flags for building library objects. pic_flag=$lt_lt_prog_compiler_pic_CXX # How to pass a linker flag through the compiler. wl=$lt_lt_prog_compiler_wl_CXX # Compiler flag to prevent dynamic linking. link_static_flag=$lt_lt_prog_compiler_static_CXX # Does compiler simultaneously support -c and -o options? compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX # Whether or not to add -lc for building shared libraries. build_libtool_need_lc=$archive_cmds_need_lc_CXX # Whether or not to disallow shared libs when runtime libs are static. allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX # Compiler flag to allow reflexive dlopens. export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX # Compiler flag to generate shared objects directly from archives. whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX # Whether the compiler copes with passing no objects directly. compiler_needs_object=$lt_compiler_needs_object_CXX # Create an old-style archive from a shared archive. old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX # Create a temporary old-style archive to link instead of a shared archive. old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX # Commands used to build a shared archive. archive_cmds=$lt_archive_cmds_CXX archive_expsym_cmds=$lt_archive_expsym_cmds_CXX # Commands used to build a loadable module if different from building # a shared archive. module_cmds=$lt_module_cmds_CXX module_expsym_cmds=$lt_module_expsym_cmds_CXX # Whether we are building with GNU ld or not. with_gnu_ld=$lt_with_gnu_ld_CXX # Flag that allows shared libraries with undefined symbols to be built. allow_undefined_flag=$lt_allow_undefined_flag_CXX # Flag that enforces no undefined symbols. no_undefined_flag=$lt_no_undefined_flag_CXX # Flag to hardcode \$libdir into a binary during linking. # This must work even if \$libdir does not exist hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX # Whether we need a single "-rpath" flag with a separated argument. hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX # Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes # DIR into the resulting binary. hardcode_direct=$hardcode_direct_CXX # Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes # DIR into the resulting binary and the resulting library dependency is # "absolute",i.e impossible to change by setting \$shlibpath_var if the # library is relocated. hardcode_direct_absolute=$hardcode_direct_absolute_CXX # Set to "yes" if using the -LDIR flag during linking hardcodes DIR # into the resulting binary. hardcode_minus_L=$hardcode_minus_L_CXX # Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR # into the resulting binary. hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX # Set to "yes" if building a shared library automatically hardcodes DIR # into the library and all subsequent libraries and executables linked # against it. hardcode_automatic=$hardcode_automatic_CXX # Set to yes if linker adds runtime paths of dependent libraries # to runtime path list. inherit_rpath=$inherit_rpath_CXX # Whether libtool must link a program against all its dependency libraries. link_all_deplibs=$link_all_deplibs_CXX # Set to "yes" if exported symbols are required. always_export_symbols=$always_export_symbols_CXX # The commands to list exported symbols. export_symbols_cmds=$lt_export_symbols_cmds_CXX # Symbols that should not be listed in the preloaded symbols. exclude_expsyms=$lt_exclude_expsyms_CXX # Symbols that must always be exported. include_expsyms=$lt_include_expsyms_CXX # Commands necessary for linking programs (against libraries) with templates. prelink_cmds=$lt_prelink_cmds_CXX # Commands necessary for finishing linking programs. postlink_cmds=$lt_postlink_cmds_CXX # Specify filename containing input files. file_list_spec=$lt_file_list_spec_CXX # How to hardcode a shared library path into an executable. hardcode_action=$hardcode_action_CXX # The directories searched by this compiler when creating a shared library. compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_CXX # Dependencies to place before and after the objects being linked to # create a shared library. predep_objects=$lt_predep_objects_CXX postdep_objects=$lt_postdep_objects_CXX predeps=$lt_predeps_CXX postdeps=$lt_postdeps_CXX # The library search path used internally by the compiler when linking # a shared library. compiler_lib_search_path=$lt_compiler_lib_search_path_CXX # ### END LIBTOOL TAG CONFIG: CXX _LT_EOF ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi # Summary # Count the max lengths dlen=0 vlen=0 while read l; do d=`echo "$l" | cut -d: -f1` v=`echo "$l" | cut -d: -f2` dl=${#d} vl=${#v} test $dlen -lt $dl && dlen=$dl test $vlen -lt $vl && vlen=$vl done << EOF $_GEANY_STATUS EOF # Print a nice top bar # description + ' : ' + value total=`expr $dlen + 3 + $vlen` for i in `seq 1 $total`; do printf '-'; done echo # And print the actual content # format is: # key1 : value1 # second key : second value while read l; do test -z "$l" && continue d=`echo "$l" | cut -d: -f1` v=`echo "$l" | cut -d: -f2` printf '%-*s : %s\n' $dlen "$d" "$v" done << EOF $_GEANY_STATUS EOF echo "" echo "Configuration is done OK." echo "" geany-2.0/aclocal.m40000644000175000017500000022156514514252330011251 00000000000000# generated automatically by aclocal 1.16.5 -*- Autoconf -*- # Copyright (C) 1996-2021 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.71],, [m4_warning([this file was generated for autoconf 2.71. You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically 'autoreconf'.])]) # =========================================================================== # https://www.gnu.org/software/autoconf-archive/ax_require_defined.html # =========================================================================== # # SYNOPSIS # # AX_REQUIRE_DEFINED(MACRO) # # DESCRIPTION # # AX_REQUIRE_DEFINED is a simple helper for making sure other macros have # been defined and thus are available for use. This avoids random issues # where a macro isn't expanded. Instead the configure script emits a # non-fatal: # # ./configure: line 1673: AX_CFLAGS_WARN_ALL: command not found # # It's like AC_REQUIRE except it doesn't expand the required macro. # # Here's an example: # # AX_REQUIRE_DEFINED([AX_CHECK_LINK_FLAG]) # # LICENSE # # Copyright (c) 2014 Mike Frysinger # # Copying and distribution of this file, with or without modification, are # permitted in any medium without royalty provided the copyright notice # and this notice are preserved. This file is offered as-is, without any # warranty. #serial 2 AC_DEFUN([AX_REQUIRE_DEFINED], [dnl m4_ifndef([$1], [m4_fatal([macro ]$1[ is not defined; is a m4 file missing?])]) ])dnl AX_REQUIRE_DEFINED # pkg.m4 - Macros to locate and use pkg-config. -*- Autoconf -*- # serial 12 (pkg-config-0.29.2) dnl Copyright © 2004 Scott James Remnant . dnl Copyright © 2012-2015 Dan Nicholson dnl dnl This program is free software; you can redistribute it and/or modify dnl it under the terms of the GNU General Public License as published by dnl the Free Software Foundation; either version 2 of the License, or dnl (at your option) any later version. dnl dnl This program is distributed in the hope that it will be useful, but dnl WITHOUT ANY WARRANTY; without even the implied warranty of dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU dnl General Public License for more details. dnl dnl You should have received a copy of the GNU General Public License dnl along with this program; if not, write to the Free Software dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA dnl 02111-1307, USA. dnl dnl As a special exception to the GNU General Public License, if you dnl distribute this file as part of a program that contains a dnl configuration script generated by Autoconf, you may include it under dnl the same distribution terms that you use for the rest of that dnl program. dnl PKG_PREREQ(MIN-VERSION) dnl ----------------------- dnl Since: 0.29 dnl dnl Verify that the version of the pkg-config macros are at least dnl MIN-VERSION. Unlike PKG_PROG_PKG_CONFIG, which checks the user's dnl installed version of pkg-config, this checks the developer's version dnl of pkg.m4 when generating configure. dnl dnl To ensure that this macro is defined, also add: dnl m4_ifndef([PKG_PREREQ], dnl [m4_fatal([must install pkg-config 0.29 or later before running autoconf/autogen])]) dnl dnl See the "Since" comment for each macro you use to see what version dnl of the macros you require. m4_defun([PKG_PREREQ], [m4_define([PKG_MACROS_VERSION], [0.29.2]) m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1, [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])]) ])dnl PKG_PREREQ dnl PKG_PROG_PKG_CONFIG([MIN-VERSION]) dnl ---------------------------------- dnl Since: 0.16 dnl dnl Search for the pkg-config tool and set the PKG_CONFIG variable to dnl first found in the path. Checks that the version of pkg-config found dnl is at least MIN-VERSION. If MIN-VERSION is not specified, 0.9.0 is dnl used since that's the first version where most current features of dnl pkg-config existed. AC_DEFUN([PKG_PROG_PKG_CONFIG], [m4_pattern_forbid([^_?PKG_[A-Z_]+$]) m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$]) m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$]) AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility]) AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path]) AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path]) if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) fi if test -n "$PKG_CONFIG"; then _pkg_min_version=m4_default([$1], [0.9.0]) AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) PKG_CONFIG="" fi fi[]dnl ])dnl PKG_PROG_PKG_CONFIG dnl PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) dnl ------------------------------------------------------------------- dnl Since: 0.18 dnl dnl Check to see whether a particular set of modules exists. Similar to dnl PKG_CHECK_MODULES(), but does not set variables or print errors. dnl dnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG]) dnl only at the first occurrence in configure.ac, so if the first place dnl it's called might be skipped (such as if it is within an "if", you dnl have to call PKG_CHECK_EXISTS manually AC_DEFUN([PKG_CHECK_EXISTS], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl if test -n "$PKG_CONFIG" && \ AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then m4_default([$2], [:]) m4_ifvaln([$3], [else $3])dnl fi]) dnl _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) dnl --------------------------------------------- dnl Internal wrapper calling pkg-config via PKG_CONFIG and setting dnl pkg_failed based on the result. m4_define([_PKG_CONFIG], [if test -n "$$1"; then pkg_cv_[]$1="$$1" elif test -n "$PKG_CONFIG"; then PKG_CHECK_EXISTS([$3], [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes ], [pkg_failed=yes]) else pkg_failed=untried fi[]dnl ])dnl _PKG_CONFIG dnl _PKG_SHORT_ERRORS_SUPPORTED dnl --------------------------- dnl Internal check to see if pkg-config supports short errors. AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], [AC_REQUIRE([PKG_PROG_PKG_CONFIG]) if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi[]dnl ])dnl _PKG_SHORT_ERRORS_SUPPORTED dnl PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], dnl [ACTION-IF-NOT-FOUND]) dnl -------------------------------------------------------------- dnl Since: 0.4.0 dnl dnl Note that if there is a possibility the first call to dnl PKG_CHECK_MODULES might not happen, you should be sure to include an dnl explicit call to PKG_PROG_PKG_CONFIG in your configure.ac AC_DEFUN([PKG_CHECK_MODULES], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl pkg_failed=no AC_MSG_CHECKING([for $2]) _PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) _PKG_CONFIG([$1][_LIBS], [libs], [$2]) m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS and $1[]_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details.]) if test $pkg_failed = yes; then AC_MSG_RESULT([no]) _PKG_SHORT_ERRORS_SUPPORTED if test $_pkg_short_errors_supported = yes; then $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1` else $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD m4_default([$4], [AC_MSG_ERROR( [Package requirements ($2) were not met: $$1_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. _PKG_TEXT])[]dnl ]) elif test $pkg_failed = untried; then AC_MSG_RESULT([no]) m4_default([$4], [AC_MSG_FAILURE( [The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. _PKG_TEXT To get pkg-config, see .])[]dnl ]) else $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS $1[]_LIBS=$pkg_cv_[]$1[]_LIBS AC_MSG_RESULT([yes]) $3 fi[]dnl ])dnl PKG_CHECK_MODULES dnl PKG_CHECK_MODULES_STATIC(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], dnl [ACTION-IF-NOT-FOUND]) dnl --------------------------------------------------------------------- dnl Since: 0.29 dnl dnl Checks for existence of MODULES and gathers its build flags with dnl static libraries enabled. Sets VARIABLE-PREFIX_CFLAGS from --cflags dnl and VARIABLE-PREFIX_LIBS from --libs. dnl dnl Note that if there is a possibility the first call to dnl PKG_CHECK_MODULES_STATIC might not happen, you should be sure to dnl include an explicit call to PKG_PROG_PKG_CONFIG in your dnl configure.ac. AC_DEFUN([PKG_CHECK_MODULES_STATIC], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl _save_PKG_CONFIG=$PKG_CONFIG PKG_CONFIG="$PKG_CONFIG --static" PKG_CHECK_MODULES($@) PKG_CONFIG=$_save_PKG_CONFIG[]dnl ])dnl PKG_CHECK_MODULES_STATIC dnl PKG_INSTALLDIR([DIRECTORY]) dnl ------------------------- dnl Since: 0.27 dnl dnl Substitutes the variable pkgconfigdir as the location where a module dnl should install pkg-config .pc files. By default the directory is dnl $libdir/pkgconfig, but the default can be changed by passing dnl DIRECTORY. The user can override through the --with-pkgconfigdir dnl parameter. AC_DEFUN([PKG_INSTALLDIR], [m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])]) m4_pushdef([pkg_description], [pkg-config installation directory @<:@]pkg_default[@:>@]) AC_ARG_WITH([pkgconfigdir], [AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],, [with_pkgconfigdir=]pkg_default) AC_SUBST([pkgconfigdir], [$with_pkgconfigdir]) m4_popdef([pkg_default]) m4_popdef([pkg_description]) ])dnl PKG_INSTALLDIR dnl PKG_NOARCH_INSTALLDIR([DIRECTORY]) dnl -------------------------------- dnl Since: 0.27 dnl dnl Substitutes the variable noarch_pkgconfigdir as the location where a dnl module should install arch-independent pkg-config .pc files. By dnl default the directory is $datadir/pkgconfig, but the default can be dnl changed by passing DIRECTORY. The user can override through the dnl --with-noarch-pkgconfigdir parameter. AC_DEFUN([PKG_NOARCH_INSTALLDIR], [m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])]) m4_pushdef([pkg_description], [pkg-config arch-independent installation directory @<:@]pkg_default[@:>@]) AC_ARG_WITH([noarch-pkgconfigdir], [AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],, [with_noarch_pkgconfigdir=]pkg_default) AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir]) m4_popdef([pkg_default]) m4_popdef([pkg_description]) ])dnl PKG_NOARCH_INSTALLDIR dnl PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE, dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) dnl ------------------------------------------- dnl Since: 0.28 dnl dnl Retrieves the value of the pkg-config variable for the given module. AC_DEFUN([PKG_CHECK_VAR], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl _PKG_CONFIG([$1], [variable="][$3]["], [$2]) AS_VAR_COPY([$1], [pkg_cv_][$1]) AS_VAR_IF([$1], [""], [$5], [$4])dnl ])dnl PKG_CHECK_VAR dnl PKG_WITH_MODULES(VARIABLE-PREFIX, MODULES, dnl [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND], dnl [DESCRIPTION], [DEFAULT]) dnl ------------------------------------------ dnl dnl Prepare a "--with-" configure option using the lowercase dnl [VARIABLE-PREFIX] name, merging the behaviour of AC_ARG_WITH and dnl PKG_CHECK_MODULES in a single macro. AC_DEFUN([PKG_WITH_MODULES], [ m4_pushdef([with_arg], m4_tolower([$1])) m4_pushdef([description], [m4_default([$5], [build with ]with_arg[ support])]) m4_pushdef([def_arg], [m4_default([$6], [auto])]) m4_pushdef([def_action_if_found], [AS_TR_SH([with_]with_arg)=yes]) m4_pushdef([def_action_if_not_found], [AS_TR_SH([with_]with_arg)=no]) m4_case(def_arg, [yes],[m4_pushdef([with_without], [--without-]with_arg)], [m4_pushdef([with_without],[--with-]with_arg)]) AC_ARG_WITH(with_arg, AS_HELP_STRING(with_without, description[ @<:@default=]def_arg[@:>@]),, [AS_TR_SH([with_]with_arg)=def_arg]) AS_CASE([$AS_TR_SH([with_]with_arg)], [yes],[PKG_CHECK_MODULES([$1],[$2],$3,$4)], [auto],[PKG_CHECK_MODULES([$1],[$2], [m4_n([def_action_if_found]) $3], [m4_n([def_action_if_not_found]) $4])]) m4_popdef([with_arg]) m4_popdef([description]) m4_popdef([def_arg]) ])dnl PKG_WITH_MODULES dnl PKG_HAVE_WITH_MODULES(VARIABLE-PREFIX, MODULES, dnl [DESCRIPTION], [DEFAULT]) dnl ----------------------------------------------- dnl dnl Convenience macro to trigger AM_CONDITIONAL after PKG_WITH_MODULES dnl check._[VARIABLE-PREFIX] is exported as make variable. AC_DEFUN([PKG_HAVE_WITH_MODULES], [ PKG_WITH_MODULES([$1],[$2],,,[$3],[$4]) AM_CONDITIONAL([HAVE_][$1], [test "$AS_TR_SH([with_]m4_tolower([$1]))" = "yes"]) ])dnl PKG_HAVE_WITH_MODULES dnl PKG_HAVE_DEFINE_WITH_MODULES(VARIABLE-PREFIX, MODULES, dnl [DESCRIPTION], [DEFAULT]) dnl ------------------------------------------------------ dnl dnl Convenience macro to run AM_CONDITIONAL and AC_DEFINE after dnl PKG_WITH_MODULES check. HAVE_[VARIABLE-PREFIX] is exported as make dnl and preprocessor variable. AC_DEFUN([PKG_HAVE_DEFINE_WITH_MODULES], [ PKG_HAVE_WITH_MODULES([$1],[$2],[$3],[$4]) AS_IF([test "$AS_TR_SH([with_]m4_tolower([$1]))" = "yes"], [AC_DEFINE([HAVE_][$1], 1, [Enable ]m4_tolower([$1])[ support])]) ])dnl PKG_HAVE_DEFINE_WITH_MODULES # Copyright (C) 2002-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version='1.16' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. m4_if([$1], [1.16.5], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) # _AM_AUTOCONF_VERSION(VERSION) # ----------------------------- # aclocal traces this macro to find the Autoconf version. # This is a private macro too. Using m4_define simplifies # the logic in aclocal, which can simply ignore this definition. m4_define([_AM_AUTOCONF_VERSION], []) # AM_SET_CURRENT_AUTOMAKE_VERSION # ------------------------------- # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], [AM_AUTOMAKE_VERSION([1.16.5])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # Copyright (C) 2011-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_AR([ACT-IF-FAIL]) # ------------------------- # Try to determine the archiver interface, and trigger the ar-lib wrapper # if it is needed. If the detection of archiver interface fails, run # ACT-IF-FAIL (default is to abort configure with a proper error message). AC_DEFUN([AM_PROG_AR], [AC_BEFORE([$0], [LT_INIT])dnl AC_BEFORE([$0], [AC_PROG_LIBTOOL])dnl AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([ar-lib])dnl AC_CHECK_TOOLS([AR], [ar lib "link -lib"], [false]) : ${AR=ar} AC_CACHE_CHECK([the archiver ($AR) interface], [am_cv_ar_interface], [AC_LANG_PUSH([C]) am_cv_ar_interface=ar AC_COMPILE_IFELSE([AC_LANG_SOURCE([[int some_variable = 0;]])], [am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&AS_MESSAGE_LOG_FD' AC_TRY_EVAL([am_ar_try]) if test "$ac_status" -eq 0; then am_cv_ar_interface=ar else am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&AS_MESSAGE_LOG_FD' AC_TRY_EVAL([am_ar_try]) if test "$ac_status" -eq 0; then am_cv_ar_interface=lib else am_cv_ar_interface=unknown fi fi rm -f conftest.lib libconftest.a ]) AC_LANG_POP([C])]) case $am_cv_ar_interface in ar) ;; lib) # Microsoft lib, so override with the ar-lib wrapper script. # FIXME: It is wrong to rewrite AR. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__AR in this case, # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something # similar. AR="$am_aux_dir/ar-lib $AR" ;; unknown) m4_default([$1], [AC_MSG_ERROR([could not determine $AR interface])]) ;; esac AC_SUBST([AR])dnl ]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- # Copyright (C) 2001-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets # $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to # '$srcdir', '$srcdir/..', or '$srcdir/../..'. # # Of course, Automake must honor this variable whenever it calls a # tool from the auxiliary directory. The problem is that $srcdir (and # therefore $ac_aux_dir as well) can be either absolute or relative, # depending on how configure is run. This is pretty annoying, since # it makes $ac_aux_dir quite unusable in subdirectories: in the top # source directory, any form will work fine, but in subdirectories a # relative path needs to be adjusted first. # # $ac_aux_dir/missing # fails when called from a subdirectory if $ac_aux_dir is relative # $top_srcdir/$ac_aux_dir/missing # fails if $ac_aux_dir is absolute, # fails when called from a subdirectory in a VPATH build with # a relative $ac_aux_dir # # The reason of the latter failure is that $top_srcdir and $ac_aux_dir # are both prefixed by $srcdir. In an in-source build this is usually # harmless because $srcdir is '.', but things will broke when you # start a VPATH build or use an absolute $srcdir. # # So we could use something similar to $top_srcdir/$ac_aux_dir/missing, # iff we strip the leading $srcdir from $ac_aux_dir. That would be: # am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` # and then we would define $MISSING as # MISSING="\${SHELL} $am_aux_dir/missing" # This will work as long as MISSING is not called from configure, because # unfortunately $(top_srcdir) has no meaning in configure. # However there are other variables, like CC, which are often used in # configure, and could therefore not use this "fixed" $ac_aux_dir. # # Another solution, used here, is to always expand $ac_aux_dir to an # absolute PATH. The drawback is that using absolute paths prevent a # configured tree to be moved without reconfiguration. AC_DEFUN([AM_AUX_DIR_EXPAND], [AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl # Expand $ac_aux_dir to an absolute path. am_aux_dir=`cd "$ac_aux_dir" && pwd` ]) # AM_COND_IF -*- Autoconf -*- # Copyright (C) 2008-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_COND_IF # _AM_COND_ELSE # _AM_COND_ENDIF # -------------- # These macros are only used for tracing. m4_define([_AM_COND_IF]) m4_define([_AM_COND_ELSE]) m4_define([_AM_COND_ENDIF]) # AM_COND_IF(COND, [IF-TRUE], [IF-FALSE]) # --------------------------------------- # If the shell condition COND is true, execute IF-TRUE, otherwise execute # IF-FALSE. Allow automake to learn about conditional instantiating macros # (the AC_CONFIG_FOOS). AC_DEFUN([AM_COND_IF], [m4_ifndef([_AM_COND_VALUE_$1], [m4_fatal([$0: no such condition "$1"])])dnl _AM_COND_IF([$1])dnl if test -z "$$1_TRUE"; then : m4_n([$2])[]dnl m4_ifval([$3], [_AM_COND_ELSE([$1])dnl else $3 ])dnl _AM_COND_ENDIF([$1])dnl fi[]dnl ]) # AM_CONDITIONAL -*- Autoconf -*- # Copyright (C) 1997-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. AC_DEFUN([AM_CONDITIONAL], [AC_PREREQ([2.52])dnl m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl AC_SUBST([$1_TRUE])dnl AC_SUBST([$1_FALSE])dnl _AM_SUBST_NOTMAKE([$1_TRUE])dnl _AM_SUBST_NOTMAKE([$1_FALSE])dnl m4_define([_AM_COND_VALUE_$1], [$2])dnl if $2; then $1_TRUE= $1_FALSE='#' else $1_TRUE='#' $1_FALSE= fi AC_CONFIG_COMMANDS_PRE( [if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then AC_MSG_ERROR([[conditional "$1" was never defined. Usually this means the macro was only invoked conditionally.]]) fi])]) # Copyright (C) 1999-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be # written in clear, in which case automake, when reading aclocal.m4, # will think it sees a *use*, and therefore will trigger all it's # C support machinery. Also note that it means that autoscan, seeing # CC etc. in the Makefile, will ask for an AC_PROG_CC use... # _AM_DEPENDENCIES(NAME) # ---------------------- # See how the compiler implements dependency checking. # NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC". # We try a few techniques and use that to set a single cache variable. # # We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was # modified to invoke _AM_DEPENDENCIES(CC); we would have a circular # dependency, and given that the user is not expected to run this macro, # just rely on AC_PROG_CC. AC_DEFUN([_AM_DEPENDENCIES], [AC_REQUIRE([AM_SET_DEPDIR])dnl AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl AC_REQUIRE([AM_MAKE_INCLUDE])dnl AC_REQUIRE([AM_DEP_TRACK])dnl m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], [$1], [CXX], [depcc="$CXX" am_compiler_list=], [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], [$1], [UPC], [depcc="$UPC" am_compiler_list=], [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], [depcc="$$1" am_compiler_list=]) AC_CACHE_CHECK([dependency style of $depcc], [am_cv_$1_dependencies_compiler_type], [if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_$1_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` fi am__universal=false m4_case([$1], [CC], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac], [CXX], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac]) for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_$1_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_$1_dependencies_compiler_type=none fi ]) AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) AM_CONDITIONAL([am__fastdep$1], [ test "x$enable_dependency_tracking" != xno \ && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) ]) # AM_SET_DEPDIR # ------------- # Choose a directory name for dependency files. # This macro is AC_REQUIREd in _AM_DEPENDENCIES. AC_DEFUN([AM_SET_DEPDIR], [AC_REQUIRE([AM_SET_LEADING_DOT])dnl AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl ]) # AM_DEP_TRACK # ------------ AC_DEFUN([AM_DEP_TRACK], [AC_ARG_ENABLE([dependency-tracking], [dnl AS_HELP_STRING( [--enable-dependency-tracking], [do not reject slow dependency extractors]) AS_HELP_STRING( [--disable-dependency-tracking], [speeds up one-time build])]) if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) AC_SUBST([AMDEPBACKSLASH])dnl _AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl AC_SUBST([am__nodep])dnl _AM_SUBST_NOTMAKE([am__nodep])dnl ]) # Generate code to set up dependency tracking. -*- Autoconf -*- # Copyright (C) 1999-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [{ # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. # TODO: see whether this extra hack can be removed once we start # requiring Autoconf 2.70 or later. AS_CASE([$CONFIG_FILES], [*\'*], [eval set x "$CONFIG_FILES"], [*], [set x $CONFIG_FILES]) shift # Used to flag and report bootstrapping failures. am_rc=0 for am_mf do # Strip MF so we end up with the name of the file. am_mf=`AS_ECHO(["$am_mf"]) | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile which includes # dependency-tracking related rules and includes. # Grep'ing the whole file directly is not great: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \ || continue am_dirpart=`AS_DIRNAME(["$am_mf"])` am_filepart=`AS_BASENAME(["$am_mf"])` AM_RUN_LOG([cd "$am_dirpart" \ && sed -e '/# am--include-marker/d' "$am_filepart" \ | $MAKE -f - am--depfiles]) || am_rc=$? done if test $am_rc -ne 0; then AC_MSG_FAILURE([Something went wrong bootstrapping makefile fragments for automatic dependency tracking. If GNU make was not used, consider re-running the configure script with MAKE="gmake" (or whatever is necessary). You can also try re-running configure with the '--disable-dependency-tracking' option to at least be able to build the package (albeit without support for automatic dependency tracking).]) fi AS_UNSET([am_dirpart]) AS_UNSET([am_filepart]) AS_UNSET([am_mf]) AS_UNSET([am_rc]) rm -f conftest-deps.mk } ])# _AM_OUTPUT_DEPENDENCY_COMMANDS # AM_OUTPUT_DEPENDENCY_COMMANDS # ----------------------------- # This macro should only be invoked once -- use via AC_REQUIRE. # # This code is only required when automatic dependency tracking is enabled. # This creates each '.Po' and '.Plo' makefile fragment that we'll need in # order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], [AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}"])]) # Do all the work for Automake. -*- Autoconf -*- # Copyright (C) 1996-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This macro actually does too much. Some checks are only needed if # your package does certain things. But this isn't really a big deal. dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O. m4_define([AC_PROG_CC], m4_defn([AC_PROG_CC]) [_AM_PROG_CC_C_O ]) # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) # ----------------------------------------------- # The call with PACKAGE and VERSION arguments is the old style # call (pre autoconf-2.50), which is being phased out. PACKAGE # and VERSION should now be passed to AC_INIT and removed from # the call to AM_INIT_AUTOMAKE. # We support both call styles for the transition. After # the next Automake release, Autoconf can make the AC_INIT # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], [AC_PREREQ([2.65])dnl m4_ifdef([_$0_ALREADY_INIT], [m4_fatal([$0 expanded multiple times ]m4_defn([_$0_ALREADY_INIT]))], [m4_define([_$0_ALREADY_INIT], m4_expansion_stack)])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl # test to see if srcdir already configured if test -f $srcdir/config.status; then AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi AC_SUBST([CYGPATH_W]) # Define the identity of the package. dnl Distinguish between old-style and new-style calls. m4_ifval([$2], [AC_DIAGNOSE([obsolete], [$0: two- and three-arguments forms are deprecated.]) m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. m4_if( m4_ifset([AC_PACKAGE_NAME], [ok]):m4_ifset([AC_PACKAGE_VERSION], [ok]), [ok:ok],, [m4_fatal([AC_INIT should be called with package and version arguments])])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl _AM_IF_OPTION([no-define],, [AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl # Some tools Automake needs. AC_REQUIRE([AM_SANITY_CHECK])dnl AC_REQUIRE([AC_ARG_PROGRAM])dnl AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) AM_MISSING_PROG([AUTOCONF], [autoconf]) AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) AM_MISSING_PROG([AUTOHEADER], [autoheader]) AM_MISSING_PROG([MAKEINFO], [makeinfo]) AC_REQUIRE([AM_PROG_INSTALL_SH])dnl AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl AC_REQUIRE([AC_PROG_MKDIR_P])dnl # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: # # AC_SUBST([mkdir_p], ['$(MKDIR_P)']) # We need awk for the "check" target (and possibly the TAP driver). The # system "awk" is bad on some platforms. AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AM_SET_LEADING_DOT])dnl _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], [_AM_PROG_TAR([v7])])]) _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], [_AM_DEPENDENCIES([CC])], [m4_define([AC_PROG_CC], m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], [_AM_DEPENDENCIES([CXX])], [m4_define([AC_PROG_CXX], m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJC], [_AM_DEPENDENCIES([OBJC])], [m4_define([AC_PROG_OBJC], m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], [_AM_DEPENDENCIES([OBJCXX])], [m4_define([AC_PROG_OBJCXX], m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl ]) # Variables for tags utilities; see am/tags.am if test -z "$CTAGS"; then CTAGS=ctags fi AC_SUBST([CTAGS]) if test -z "$ETAGS"; then ETAGS=etags fi AC_SUBST([ETAGS]) if test -z "$CSCOPE"; then CSCOPE=cscope fi AC_SUBST([CSCOPE]) AC_REQUIRE([AM_SILENT_RULES])dnl dnl The testsuite driver may need to know about EXEEXT, so add the dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. AC_CONFIG_COMMANDS_PRE(dnl [m4_provide_if([_AM_COMPILER_EXEEXT], [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl # POSIX will say in a future version that running "rm -f" with no argument # is OK; and we want to be able to make that assumption in our Makefile # recipes. So use an aggressive probe to check that the usage we want is # actually supported "in the wild" to an acceptable degree. # See automake bug#10828. # To make any issue more visible, cause the running configure to be aborted # by default if the 'rm' program in use doesn't match our expectations; the # user can still override this though. if rm -f && rm -fr && rm -rf; then : OK; else cat >&2 <<'END' Oops! Your 'rm' program seems unable to run without file operands specified on the command line, even when the '-f' option is present. This is contrary to the behaviour of most rm programs out there, and not conforming with the upcoming POSIX standard: Please tell bug-automake@gnu.org about your system, including the value of your $PATH and any error possibly output before this message. This can help us improve future automake versions. END if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then echo 'Configuration will proceed anyway, since you have set the' >&2 echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 echo >&2 else cat >&2 <<'END' Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM to "yes", and re-run configure. END AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) fi fi dnl The trailing newline in this macro's definition is deliberate, for dnl backward compatibility and to allow trailing 'dnl'-style comments dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841. ]) dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further dnl mangled by Autoconf and run in a shell conditional statement. m4_define([_AC_COMPILER_EXEEXT], m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) # When config.status generates a header, we must update the stamp-h file. # This file resides in the same directory as the config header # that is generated. The stamp files are numbered to have different names. # Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the # loop where config.status creates the headers, so we can generate # our stamp files there. AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], [# Compute $1's index in $config_headers. _am_arg=$1 _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) # Copyright (C) 2001-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl if test x"${install_sh+set}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi AC_SUBST([install_sh])]) # Copyright (C) 2003-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. AC_DEFUN([AM_SET_LEADING_DOT], [rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null AC_SUBST([am__leading_dot])]) # Check to see how 'make' treats includes. -*- Autoconf -*- # Copyright (C) 2001-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MAKE_INCLUDE() # ----------------- # Check whether make has an 'include' directive that can support all # the idioms we need for our automatic dependency tracking code. AC_DEFUN([AM_MAKE_INCLUDE], [AC_MSG_CHECKING([whether ${MAKE-make} supports the include directive]) cat > confinc.mk << 'END' am__doit: @echo this is the am__doit target >confinc.out .PHONY: am__doit END am__include="#" am__quote= # BSD make does it like this. echo '.include "confinc.mk" # ignored' > confmf.BSD # Other make implementations (GNU, Solaris 10, AIX) do it like this. echo 'include confinc.mk # ignored' > confmf.GNU _am_result=no for s in GNU BSD; do AM_RUN_LOG([${MAKE-make} -f confmf.$s && cat confinc.out]) AS_CASE([$?:`cat confinc.out 2>/dev/null`], ['0:this is the am__doit target'], [AS_CASE([$s], [BSD], [am__include='.include' am__quote='"'], [am__include='include' am__quote=''])]) if test "$am__include" != "#"; then _am_result="yes ($s style)" break fi done rm -f confinc.* confmf.* AC_MSG_RESULT([${_am_result}]) AC_SUBST([am__include])]) AC_SUBST([am__quote])]) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- # Copyright (C) 1997-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ AC_DEFUN([AM_MISSING_PROG], [AC_REQUIRE([AM_MISSING_HAS_RUN]) $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) # AM_MISSING_HAS_RUN # ------------------ # Define MISSING if not defined so far and test if it is modern enough. # If it is, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([missing])dnl if test x"${MISSING+set}" != xset; then MISSING="\${SHELL} '$am_aux_dir/missing'" fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then am_missing_run="$MISSING " else am_missing_run= AC_MSG_WARN(['missing' script is too old or missing]) fi ]) # Helper functions for option handling. -*- Autoconf -*- # Copyright (C) 2001-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_MANGLE_OPTION(NAME) # ----------------------- AC_DEFUN([_AM_MANGLE_OPTION], [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) # _AM_SET_OPTION(NAME) # -------------------- # Set option NAME. Presently that only means defining a flag for this option. AC_DEFUN([_AM_SET_OPTION], [m4_define(_AM_MANGLE_OPTION([$1]), [1])]) # _AM_SET_OPTIONS(OPTIONS) # ------------------------ # OPTIONS is a space-separated list of Automake options. AC_DEFUN([_AM_SET_OPTIONS], [m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) # _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) # ------------------------------------------- # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) # Copyright (C) 1999-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_PROG_CC_C_O # --------------- # Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC # to automatically call this. AC_DEFUN([_AM_PROG_CC_C_O], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([compile])dnl AC_LANG_PUSH([C])dnl AC_CACHE_CHECK( [whether $CC understands -c and -o together], [am_cv_prog_cc_c_o], [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])]) # Make sure it works both with $CC and with simple cc. # Following AC_PROG_CC_C_O, we do the test twice because some # compilers refuse to overwrite an existing .o file with -o, # though they will create one. am_cv_prog_cc_c_o=yes for am_i in 1 2; do if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \ && test -f conftest2.$ac_objext; then : OK else am_cv_prog_cc_c_o=no break fi done rm -f core conftest* unset am_i]) if test "$am_cv_prog_cc_c_o" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi AC_LANG_POP([C])]) # For backward compatibility. AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) # Copyright (C) 1999-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PATH_PYTHON([MINIMUM-VERSION], [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) # --------------------------------------------------------------------------- # Adds support for distributing Python modules and packages. To # install modules, copy them to $(pythondir), using the python_PYTHON # automake variable. To install a package with the same name as the # automake package, install to $(pkgpythondir), or use the # pkgpython_PYTHON automake variable. # # The variables $(pyexecdir) and $(pkgpyexecdir) are provided as # locations to install python extension modules (shared libraries). # Another macro is required to find the appropriate flags to compile # extension modules. # # If your package is configured with a different prefix to python, # users will have to add the install directory to the PYTHONPATH # environment variable, or create a .pth file (see the python # documentation for details). # # If the MINIMUM-VERSION argument is passed, AM_PATH_PYTHON will # cause an error if the version of python installed on the system # doesn't meet the requirement. MINIMUM-VERSION should consist of # numbers and dots only. AC_DEFUN([AM_PATH_PYTHON], [ dnl Find a Python interpreter. Python versions prior to 2.0 are not dnl supported. (2.0 was released on October 16, 2000). m4_define_default([_AM_PYTHON_INTERPRETER_LIST], [python python2 python3 dnl python3.11 python3.10 dnl python3.9 python3.8 python3.7 python3.6 python3.5 python3.4 python3.3 dnl python3.2 python3.1 python3.0 dnl python2.7 python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 dnl python2.0]) AC_ARG_VAR([PYTHON], [the Python interpreter]) m4_if([$1],[],[ dnl No version check is needed. # Find any Python interpreter. if test -z "$PYTHON"; then AC_PATH_PROGS([PYTHON], _AM_PYTHON_INTERPRETER_LIST, :) fi am_display_PYTHON=python ], [ dnl A version check is needed. if test -n "$PYTHON"; then # If the user set $PYTHON, use it and don't search something else. AC_MSG_CHECKING([whether $PYTHON version is >= $1]) AM_PYTHON_CHECK_VERSION([$PYTHON], [$1], [AC_MSG_RESULT([yes])], [AC_MSG_RESULT([no]) AC_MSG_ERROR([Python interpreter is too old])]) am_display_PYTHON=$PYTHON else # Otherwise, try each interpreter until we find one that satisfies # VERSION. AC_CACHE_CHECK([for a Python interpreter with version >= $1], [am_cv_pathless_PYTHON],[ for am_cv_pathless_PYTHON in _AM_PYTHON_INTERPRETER_LIST none; do test "$am_cv_pathless_PYTHON" = none && break AM_PYTHON_CHECK_VERSION([$am_cv_pathless_PYTHON], [$1], [break]) done]) # Set $PYTHON to the absolute path of $am_cv_pathless_PYTHON. if test "$am_cv_pathless_PYTHON" = none; then PYTHON=: else AC_PATH_PROG([PYTHON], [$am_cv_pathless_PYTHON]) fi am_display_PYTHON=$am_cv_pathless_PYTHON fi ]) if test "$PYTHON" = :; then dnl Run any user-specified action, or abort. m4_default([$3], [AC_MSG_ERROR([no suitable Python interpreter found])]) else dnl Query Python for its version number. Although site.py simply uses dnl sys.version[:3], printing that failed with Python 3.10, since the dnl trailing zero was eliminated. So now we output just the major dnl and minor version numbers, as numbers. Apparently the tertiary dnl version is not of interest. dnl AC_CACHE_CHECK([for $am_display_PYTHON version], [am_cv_python_version], [am_cv_python_version=`$PYTHON -c "import sys; print ('%u.%u' % sys.version_info[[:2]])"`]) AC_SUBST([PYTHON_VERSION], [$am_cv_python_version]) dnl At times, e.g., when building shared libraries, you may want dnl to know which OS platform Python thinks this is. dnl AC_CACHE_CHECK([for $am_display_PYTHON platform], [am_cv_python_platform], [am_cv_python_platform=`$PYTHON -c "import sys; sys.stdout.write(sys.platform)"`]) AC_SUBST([PYTHON_PLATFORM], [$am_cv_python_platform]) dnl emacs-page dnl If --with-python-sys-prefix is given, use the values of sys.prefix dnl and sys.exec_prefix for the corresponding values of PYTHON_PREFIX dnl and PYTHON_EXEC_PREFIX. Otherwise, use the GNU ${prefix} and dnl ${exec_prefix} variables. dnl dnl The two are made distinct variables so they can be overridden if dnl need be, although general consensus is that you shouldn't need dnl this separation. dnl dnl Also allow directly setting the prefixes via configure options, dnl overriding any default. dnl if test "x$prefix" = xNONE; then am__usable_prefix=$ac_default_prefix else am__usable_prefix=$prefix fi # Allow user to request using sys.* values from Python, # instead of the GNU $prefix values. AC_ARG_WITH([python-sys-prefix], [AS_HELP_STRING([--with-python-sys-prefix], [use Python's sys.prefix and sys.exec_prefix values])], [am_use_python_sys=:], [am_use_python_sys=false]) # Allow user to override whatever the default Python prefix is. AC_ARG_WITH([python_prefix], [AS_HELP_STRING([--with-python_prefix], [override the default PYTHON_PREFIX])], [am_python_prefix_subst=$withval am_cv_python_prefix=$withval AC_MSG_CHECKING([for explicit $am_display_PYTHON prefix]) AC_MSG_RESULT([$am_cv_python_prefix])], [ if $am_use_python_sys; then # using python sys.prefix value, not GNU AC_CACHE_CHECK([for python default $am_display_PYTHON prefix], [am_cv_python_prefix], [am_cv_python_prefix=`$PYTHON -c "import sys; sys.stdout.write(sys.prefix)"`]) dnl If sys.prefix is a subdir of $prefix, replace the literal value of dnl $prefix with a variable reference so it can be overridden. case $am_cv_python_prefix in $am__usable_prefix*) am__strip_prefix=`echo "$am__usable_prefix" | sed 's|.|.|g'` am_python_prefix_subst=`echo "$am_cv_python_prefix" | sed "s,^$am__strip_prefix,\\${prefix},"` ;; *) am_python_prefix_subst=$am_cv_python_prefix ;; esac else # using GNU prefix value, not python sys.prefix am_python_prefix_subst='${prefix}' am_python_prefix=$am_python_prefix_subst AC_MSG_CHECKING([for GNU default $am_display_PYTHON prefix]) AC_MSG_RESULT([$am_python_prefix]) fi]) # Substituting python_prefix_subst value. AC_SUBST([PYTHON_PREFIX], [$am_python_prefix_subst]) # emacs-page Now do it all over again for Python exec_prefix, but with yet # another conditional: fall back to regular prefix if that was specified. AC_ARG_WITH([python_exec_prefix], [AS_HELP_STRING([--with-python_exec_prefix], [override the default PYTHON_EXEC_PREFIX])], [am_python_exec_prefix_subst=$withval am_cv_python_exec_prefix=$withval AC_MSG_CHECKING([for explicit $am_display_PYTHON exec_prefix]) AC_MSG_RESULT([$am_cv_python_exec_prefix])], [ # no explicit --with-python_exec_prefix, but if # --with-python_prefix was given, use its value for python_exec_prefix too. AS_IF([test -n "$with_python_prefix"], [am_python_exec_prefix_subst=$with_python_prefix am_cv_python_exec_prefix=$with_python_prefix AC_MSG_CHECKING([for python_prefix-given $am_display_PYTHON exec_prefix]) AC_MSG_RESULT([$am_cv_python_exec_prefix])], [ # Set am__usable_exec_prefix whether using GNU or Python values, # since we use that variable for pyexecdir. if test "x$exec_prefix" = xNONE; then am__usable_exec_prefix=$am__usable_prefix else am__usable_exec_prefix=$exec_prefix fi # if $am_use_python_sys; then # using python sys.exec_prefix, not GNU AC_CACHE_CHECK([for python default $am_display_PYTHON exec_prefix], [am_cv_python_exec_prefix], [am_cv_python_exec_prefix=`$PYTHON -c "import sys; sys.stdout.write(sys.exec_prefix)"`]) dnl If sys.exec_prefix is a subdir of $exec_prefix, replace the dnl literal value of $exec_prefix with a variable reference so it can dnl be overridden. case $am_cv_python_exec_prefix in $am__usable_exec_prefix*) am__strip_prefix=`echo "$am__usable_exec_prefix" | sed 's|.|.|g'` am_python_exec_prefix_subst=`echo "$am_cv_python_exec_prefix" | sed "s,^$am__strip_prefix,\\${exec_prefix},"` ;; *) am_python_exec_prefix_subst=$am_cv_python_exec_prefix ;; esac else # using GNU $exec_prefix, not python sys.exec_prefix am_python_exec_prefix_subst='${exec_prefix}' am_python_exec_prefix=$am_python_exec_prefix_subst AC_MSG_CHECKING([for GNU default $am_display_PYTHON exec_prefix]) AC_MSG_RESULT([$am_python_exec_prefix]) fi])]) # Substituting python_exec_prefix_subst. AC_SUBST([PYTHON_EXEC_PREFIX], [$am_python_exec_prefix_subst]) # Factor out some code duplication into this shell variable. am_python_setup_sysconfig="\ import sys # Prefer sysconfig over distutils.sysconfig, for better compatibility # with python 3.x. See automake bug#10227. try: import sysconfig except ImportError: can_use_sysconfig = 0 else: can_use_sysconfig = 1 # Can't use sysconfig in CPython 2.7, since it's broken in virtualenvs: # try: from platform import python_implementation if python_implementation() == 'CPython' and sys.version[[:3]] == '2.7': can_use_sysconfig = 0 except ImportError: pass" dnl emacs-page Set up 4 directories: dnl 1. pythondir: where to install python scripts. This is the dnl site-packages directory, not the python standard library dnl directory like in previous automake betas. This behavior dnl is more consistent with lispdir.m4 for example. dnl Query distutils for this directory. dnl AC_CACHE_CHECK([for $am_display_PYTHON script directory (pythondir)], [am_cv_python_pythondir], [if test "x$am_cv_python_prefix" = x; then am_py_prefix=$am__usable_prefix else am_py_prefix=$am_cv_python_prefix fi am_cv_python_pythondir=`$PYTHON -c " $am_python_setup_sysconfig if can_use_sysconfig: if hasattr(sysconfig, 'get_default_scheme'): scheme = sysconfig.get_default_scheme() else: scheme = sysconfig._get_default_scheme() if scheme == 'posix_local': # Debian's default scheme installs to /usr/local/ but we want to find headers in /usr/ scheme = 'posix_prefix' sitedir = sysconfig.get_path('purelib', scheme, vars={'base':'$am_py_prefix'}) else: from distutils import sysconfig sitedir = sysconfig.get_python_lib(0, 0, prefix='$am_py_prefix') sys.stdout.write(sitedir)"` # case $am_cv_python_pythondir in $am_py_prefix*) am__strip_prefix=`echo "$am_py_prefix" | sed 's|.|.|g'` am_cv_python_pythondir=`echo "$am_cv_python_pythondir" | sed "s,^$am__strip_prefix,\\${PYTHON_PREFIX},"` ;; *) case $am_py_prefix in /usr|/System*) ;; *) am_cv_python_pythondir="\${PYTHON_PREFIX}/lib/python$PYTHON_VERSION/site-packages" ;; esac ;; esac ]) AC_SUBST([pythondir], [$am_cv_python_pythondir]) dnl 2. pkgpythondir: $PACKAGE directory under pythondir. Was dnl PYTHON_SITE_PACKAGE in previous betas, but this naming is dnl more consistent with the rest of automake. dnl AC_SUBST([pkgpythondir], [\${pythondir}/$PACKAGE]) dnl 3. pyexecdir: directory for installing python extension modules dnl (shared libraries). dnl Query distutils for this directory. dnl AC_CACHE_CHECK([for $am_display_PYTHON extension module directory (pyexecdir)], [am_cv_python_pyexecdir], [if test "x$am_cv_python_exec_prefix" = x; then am_py_exec_prefix=$am__usable_exec_prefix else am_py_exec_prefix=$am_cv_python_exec_prefix fi am_cv_python_pyexecdir=`$PYTHON -c " $am_python_setup_sysconfig if can_use_sysconfig: if hasattr(sysconfig, 'get_default_scheme'): scheme = sysconfig.get_default_scheme() else: scheme = sysconfig._get_default_scheme() if scheme == 'posix_local': # Debian's default scheme installs to /usr/local/ but we want to find headers in /usr/ scheme = 'posix_prefix' sitedir = sysconfig.get_path('platlib', scheme, vars={'platbase':'$am_py_exec_prefix'}) else: from distutils import sysconfig sitedir = sysconfig.get_python_lib(1, 0, prefix='$am_py_exec_prefix') sys.stdout.write(sitedir)"` # case $am_cv_python_pyexecdir in $am_py_exec_prefix*) am__strip_prefix=`echo "$am_py_exec_prefix" | sed 's|.|.|g'` am_cv_python_pyexecdir=`echo "$am_cv_python_pyexecdir" | sed "s,^$am__strip_prefix,\\${PYTHON_EXEC_PREFIX},"` ;; *) case $am_py_exec_prefix in /usr|/System*) ;; *) am_cv_python_pyexecdir="\${PYTHON_EXEC_PREFIX}/lib/python$PYTHON_VERSION/site-packages" ;; esac ;; esac ]) AC_SUBST([pyexecdir], [$am_cv_python_pyexecdir]) dnl 4. pkgpyexecdir: $(pyexecdir)/$(PACKAGE) dnl AC_SUBST([pkgpyexecdir], [\${pyexecdir}/$PACKAGE]) dnl Run any user-specified action. $2 fi ]) # AM_PYTHON_CHECK_VERSION(PROG, VERSION, [ACTION-IF-TRUE], [ACTION-IF-FALSE]) # --------------------------------------------------------------------------- # Run ACTION-IF-TRUE if the Python interpreter PROG has version >= VERSION. # Run ACTION-IF-FALSE otherwise. # This test uses sys.hexversion instead of the string equivalent (first # word of sys.version), in order to cope with versions such as 2.2c1. # This supports Python 2.0 or higher. (2.0 was released on October 16, 2000). AC_DEFUN([AM_PYTHON_CHECK_VERSION], [prog="import sys # split strings by '.' and convert to numeric. Append some zeros # because we need at least 4 digits for the hex conversion. # map returns an iterator in Python 3.0 and a list in 2.x minver = list(map(int, '$2'.split('.'))) + [[0, 0, 0]] minverhex = 0 # xrange is not present in Python 3.0 and range returns an iterator for i in list(range(0, 4)): minverhex = (minverhex << 8) + minver[[i]] sys.exit(sys.hexversion < minverhex)" AS_IF([AM_RUN_LOG([$1 -c "$prog"])], [$3], [$4])]) # Copyright (C) 2001-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_RUN_LOG(COMMAND) # ------------------- # Run COMMAND, save the exit status in ac_status, and log it. # (This has been adapted from Autoconf's _AC_RUN_LOG macro.) AC_DEFUN([AM_RUN_LOG], [{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD (exit $ac_status); }]) # Check to make sure that the build environment is sane. -*- Autoconf -*- # Copyright (C) 1996-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[[\\\"\#\$\&\'\`$am_lf]]*) AC_MSG_ERROR([unsafe absolute working directory name]);; esac case $srcdir in *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; esac # Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( am_has_slept=no for am_try in 1 2; do echo "timestamp, slept: $am_has_slept" > conftest.file set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$[*]" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi if test "$[*]" != "X $srcdir/configure conftest.file" \ && test "$[*]" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken alias in your environment]) fi if test "$[2]" = conftest.file || test $am_try -eq 2; then break fi # Just in case. sleep 1 am_has_slept=yes done test "$[2]" = conftest.file ) then # Ok. : else AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi AC_MSG_RESULT([yes]) # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= if grep 'slept: no' conftest.file >/dev/null 2>&1; then ( sleep 1 ) & am_sleep_pid=$! fi AC_CONFIG_COMMANDS_PRE( [AC_MSG_CHECKING([that generated files are newer than configure]) if test -n "$am_sleep_pid"; then # Hide warnings about reused PIDs. wait $am_sleep_pid 2>/dev/null fi AC_MSG_RESULT([done])]) rm -f conftest.file ]) # Copyright (C) 2009-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_SILENT_RULES([DEFAULT]) # -------------------------- # Enable less verbose build rules; with the default set to DEFAULT # ("yes" being less verbose, "no" or empty being verbose). AC_DEFUN([AM_SILENT_RULES], [AC_ARG_ENABLE([silent-rules], [dnl AS_HELP_STRING( [--enable-silent-rules], [less verbose build output (undo: "make V=1")]) AS_HELP_STRING( [--disable-silent-rules], [verbose build output (undo: "make V=0")])dnl ]) case $enable_silent_rules in @%:@ ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; esac dnl dnl A few 'make' implementations (e.g., NonStop OS and NextStep) dnl do not support nested variable expansions. dnl See automake bug#9928 and bug#10237. am_make=${MAKE-make} AC_CACHE_CHECK([whether $am_make supports nested variables], [am_cv_make_support_nested_variables], [if AS_ECHO([['TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi]) if test $am_cv_make_support_nested_variables = yes; then dnl Using '$V' instead of '$(V)' breaks IRIX make. AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AC_SUBST([AM_V])dnl AM_SUBST_NOTMAKE([AM_V])dnl AC_SUBST([AM_DEFAULT_V])dnl AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl AC_SUBST([AM_DEFAULT_VERBOSITY])dnl AM_BACKSLASH='\' AC_SUBST([AM_BACKSLASH])dnl _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl ]) # Copyright (C) 2001-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_STRIP # --------------------- # One issue with vendor 'install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip # is unlikely to handle the host's binaries. # Fortunately install-sh will honor a STRIPPROG variable, so we # always use install-sh in "make install-strip", and initialize # STRIPPROG with the value of the STRIP variable (set by the user). AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl # Installed binaries are usually stripped using 'strip' when the user # run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the 'STRIP' environment variable to overrule this program. dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) # Copyright (C) 2006-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_SUBST_NOTMAKE(VARIABLE) # --------------------------- # Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. # This macro is traced by Automake. AC_DEFUN([_AM_SUBST_NOTMAKE]) # AM_SUBST_NOTMAKE(VARIABLE) # -------------------------- # Public sister of _AM_SUBST_NOTMAKE. AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- # Copyright (C) 2004-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_PROG_TAR(FORMAT) # -------------------- # Check how to create a tarball in format FORMAT. # FORMAT should be one of 'v7', 'ustar', or 'pax'. # # Substitute a variable $(am__tar) that is a command # writing to stdout a FORMAT-tarball containing the directory # $tardir. # tardir=directory && $(am__tar) > result.tar # # Substitute a variable $(am__untar) that extract such # a tarball read from stdin. # $(am__untar) < result.tar # AC_DEFUN([_AM_PROG_TAR], [# Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AC_SUBST([AMTAR], ['$${TAR-tar}']) # We'll loop over all known methods to create a tar archive until one works. _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' m4_if([$1], [v7], [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], [m4_case([$1], [ustar], [# The POSIX 1988 'ustar' format is defined with fixed-size fields. # There is notably a 21 bits limit for the UID and the GID. In fact, # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 # and bug#13588). am_max_uid=2097151 # 2^21 - 1 am_max_gid=$am_max_uid # The $UID and $GID variables are not portable, so we need to resort # to the POSIX-mandated id(1) utility. Errors in the 'id' calls # below are definitely unexpected, so allow the users to see them # (that is, avoid stderr redirection). am_uid=`id -u || echo unknown` am_gid=`id -g || echo unknown` AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) if test $am_uid -le $am_max_uid; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) _am_tools=none fi AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) if test $am_gid -le $am_max_gid; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) _am_tools=none fi], [pax], [], [m4_fatal([Unknown tar format])]) AC_MSG_CHECKING([how to create a $1 tar archive]) # Go ahead even if we have the value already cached. We do so because we # need to set the values for the 'am__tar' and 'am__untar' variables. _am_tools=${am_cv_prog_tar_$1-$_am_tools} for _am_tool in $_am_tools; do case $_am_tool in gnutar) for _am_tar in tar gnutar gtar; do AM_RUN_LOG([$_am_tar --version]) && break done am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' am__untar="$_am_tar -xf -" ;; plaintar) # Must skip GNU tar: if it does not support --format= it doesn't create # ustar tarball either. (tar --version) >/dev/null 2>&1 && continue am__tar='tar chf - "$$tardir"' am__tar_='tar chf - "$tardir"' am__untar='tar xf -' ;; pax) am__tar='pax -L -x $1 -w "$$tardir"' am__tar_='pax -L -x $1 -w "$tardir"' am__untar='pax -r' ;; cpio) am__tar='find "$$tardir" -print | cpio -o -H $1 -L' am__tar_='find "$tardir" -print | cpio -o -H $1 -L' am__untar='cpio -i -H $1 -d' ;; none) am__tar=false am__tar_=false am__untar=false ;; esac # If the value was cached, stop now. We just wanted to have am__tar # and am__untar set. test -n "${am_cv_prog_tar_$1}" && break # tar/untar a dummy directory, and stop if the command works. rm -rf conftest.dir mkdir conftest.dir echo GrepMe > conftest.dir/file AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) rm -rf conftest.dir if test -s conftest.tar; then AM_RUN_LOG([$am__untar /dev/null 2>&1 && break fi done rm -rf conftest.dir AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) AC_MSG_RESULT([$am_cv_prog_tar_$1])]) AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR m4_include([m4/ax_cxx_compile_stdcxx.m4]) m4_include([m4/ax_cxx_compile_stdcxx_17.m4]) m4_include([m4/geany-binreloc.m4]) m4_include([m4/geany-docutils.m4]) m4_include([m4/geany-doxygen.m4]) m4_include([m4/geany-gtk.m4]) m4_include([m4/geany-gtkdoc-header.m4]) m4_include([m4/geany-lib.m4]) m4_include([m4/geany-mac-integration.m4]) m4_include([m4/geany-mingw.m4]) m4_include([m4/geany-plugins.m4]) m4_include([m4/geany-prog-cxx.m4]) m4_include([m4/geany-revision.m4]) m4_include([m4/geany-socket.m4]) m4_include([m4/geany-status.m4]) m4_include([m4/geany-the-force.m4]) m4_include([m4/geany-utils.m4]) m4_include([m4/geany-vte.m4]) m4_include([m4/gettext.m4]) m4_include([m4/iconv.m4]) m4_include([m4/intlmacosx.m4]) m4_include([m4/lib-ld.m4]) m4_include([m4/lib-link.m4]) m4_include([m4/lib-prefix.m4]) m4_include([m4/libtool.m4]) m4_include([m4/ltoptions.m4]) m4_include([m4/ltsugar.m4]) m4_include([m4/ltversion.m4]) m4_include([m4/lt~obsolete.m4]) m4_include([m4/nls.m4]) m4_include([m4/po.m4]) m4_include([m4/progtest.m4]) geany-2.0/TODO0000644000175000017500000000272514514252267010105 00000000000000TODO List: ---------- Note: features included in brackets have lower priority. Fix bugs: o tagmanager fails on UTF-16/32 Next version or later: o better file template {filename} wildcard replacement +{BASENAME} o improve line breaking mode o print text size/zoom option o documentation: list and explain filetype modes o common default highlighting styles configurable for all programming languages (done for C-like filetypes using filetypes.common named styles) o asynchronous build commands on Windows o (filetype-independent run command in build dialog & keybinding) o (better custom filetype support) o (custom template insertion - so user can add licenses, etc) o (selectable menu of arguments to use for Make, from Make Custom) o (DBUS) o (sci macro support - as a plugin?) o (tango-like icons for the symbol list) o (per-workspace instances with socket support - see workspace-sockets branch) Someday: o stable plugin ABI? (Split up geany_data, prefs, GeanyKeyCommand enum into groups) o review documentation Wishlist -------- Note: these items might not get worked on. o (calltip support for more non-C-like languages that use function_name(arguments) syntax - see python.c:parseArglist()) o (better tags support for popular languages? - this is a moving target...) o (support for adding syntax highlighting dynamically?) o Some kind of support for CTags tags files o Python plugin interface (different concept from Lua scripting) geany-2.0/HACKING0000644000175000017500000007646114514252267010414 00000000000000============= Hacking Geany ============= .. contents:: General ======= About this file --------------- This file contains information for anyone wanting to work on the Geany codebase. You should be aware of the open source licenses used - see the README file or the documentation. It is reStructuredText; the source file is HACKING. You can generate this file by: * Passing the *--enable-html-docs* option to ``configure``. * Running ``make`` from the doc/ subdirectory. Writing plugins --------------- * src/plugindata.h contains the plugin API data types. * See plugins/demoplugin.c for a very basic example plugin. * src/plugins.c loads and unloads plugins (you shouldn't need to read this really). * The API documentation contains a few basic guidelines and hints to write plugins. You should generate and read the plugin API documentation, see below. Plugin API documentation ^^^^^^^^^^^^^^^^^^^^^^^^ You can generate documentation for the plugin API using the doxygen tool: * Pass the *--enable-api-docs* option to ``configure``. * Run ``make`` from the doc/ subdirectory. The documentation will be output to doc/reference/index.html. Alternatively you can view the API documentation online at https://www.geany.org/manual/reference/. Pull requests ------------- Making pull requests on Github is the preferred way of contributing for geany. .. note:: For helping you to get started: https://help.github.com/articles/fork-a-repo See `Rules to contribute`_ for more information. Patches ------- We are happy to receive patches, but the preferred way is to make a pull request on our Github repository. If you don't want to make a pull request, you can send your patches on the devel mailing list, but the rules are the same: see `Rules to contribute`_ for more information. In general it's best to provide git-formatted patches made from the current Git (see `Committing`_):: $ git commit -a $ git format-patch HEAD^ We also accept patches against other releases, but it's more work for us. If you're not using Git, although you're strongly suggested to use it, you can use the diff command:: $ diff -u originalpath modifiedpath > new-feature.patch However, such a patch won't contain the authoring information nor the patch's description. .. note:: Please make sure patches follow the style of existing code - In particular, use tabs for indentation. See `Coding`_. Rules to contribute ------------------- Keep in mind this is best to check with us by email on mailing list whether a new feature is appropriate and whether someone is already working on similar code. Please, make sure contributions you make follow these rules: * changes should be made in a dedicated branch for pull requests. * only one feature should be in each pull request (or patch). * pull requests (or patches) should not contain changes unrelated to the feature, and commits should be sensible units of change. * the submitter should squash together corrections that are part of the development process, especially correcting your own mistakes. * Please make sure your modifications follow the style of existing code: see `Coding`_ for more information. See `Committing`_ for more information. Windows tools ------------- * Git: https://git-scm.com/ and https://gitforwindows.org/ * diff, grep, etc: https://www.msys2.org/ or https://unxutils.sourceforge.net/ See also the Geany wiki on how to build Geany on Windows at https://wiki.geany.org/howtos/win32/msys2. File organization ----------------- callbacks.c is just for Glade callbacks. Avoid adding code to geany.h if it will fit better elsewhere. See the top of each ``src/*.c`` file for a brief description of what it's for. Plugin API code --------------- Please be aware that anything with a doc-comment (a comment with an extra asterisk: ``/**``) is something in the plugin API. Things like enums and structs can usually still be appended to, ensuring that all the existing elements stay in place - this will keep the ABI stable. .. warning:: Some structs like GeanyCallback cannot be appended to without breaking the ABI because they are used to declare structs by plugins, not just for accessing struct members through a pointer. Normally structs should never be allocated by plugins. Keeping the plugin ABI stable ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ In general the ABI changes as little as we can manage. The ABI number must match exactly between Geany and plugins, so an ABI change breaks all plugins until they are re-compiled. But sometimes it is absolutely necessary. Removing a feature or significantly changing the semantics of an existing feature require an ABI change since existing plugins may no longer work with the modified version of Geany. The API identifying number is increased whenever anything is added to the API so plugins can test if the feature is available. The API number required by a plugin needs only to be lower than the API Geany provides, so an increase in API number without a change in ABI will not stop plugins that need a lower number from working. If you're reordering or changing existing elements of structs that are used as part of the plugin API, you must increment GEANY_ABI_VERSION in plugindata.h. This is usually not needed if you're just appending fields to structs. The GEANY_API_VERSION value should be incremented for any changes to the plugin API, including appending elements. If you're in any doubt when making changes to plugin API code, just ask us. Plugin API/ABI design ^^^^^^^^^^^^^^^^^^^^^ You should not make plugins rely on the size of a struct. This means: * Don't let plugins allocate any structs (stack or heap). * Don't let plugins index any arrays of structs. * Don't add any array fields to structs in case we want to change the array size later. Doc-comments ^^^^^^^^^^^^ * The @file tag can go in the source .c file, but use the .h header name so it appears normally in the generated documentation. See ui_utils.c for an example. * Function doc-comments should always go in the source file, not the header, so they can be updated if/when the implementation changes. Glade ----- Add user-interface widgets to the Glade 3 file ``data/geany.glade``. Callbacks for the user-interface should go in ``src/callbacks.c``. Use Glade 3.8.5. The 3.8 series still supports GTK+ 2, and earlier point releases did not preserve the order of XML elements, leading to unmanageable diffs. GTK versions & API documentation -------------------------------- Geany requires GTK >= 3.0 and GLib >= 2.32. API symbols from newer GTK/GLib versions should be avoided or made optional to keep the source code building on older systems. It is recommended to use the 3.0 API documentation of the GTK libs (including GLib, GDK and Pango) has the advantages that you don't get confused by any newer API additions and you don't have to take care about whether you can use them or not. You might want to pass the ``-DGLIB_VERSION_MAX_ALLOWED=GLIB_VERSION_2_32`` C preprocessor flag to get warnings about newer symbols from the GLib. On the contrary, you might also want to get deprecation warnings for symbols deprecated in newer versions, typically when preparing a dependency bump or trying to improve forward compatibility. To do so, use the ``-UGLIB_VERSION_MIN_REQUIRED`` flag for GLib deprecations, and ``-UGDK_DISABLE_DEPRECATION_WARNINGS`` for GTK and GDK ones. To change the lower deprecation bound for GLib (and then get warnings about symbols deprecated more recently) instead of simply removing it entirely, use ``-UGLIB_VERSION_MIN_REQUIRED -DGLIB_VERSION_MIN_REQUIRED=GLIB_VERSION_X_YY``. See `Compiler options & warnings`_ for how to set such flags. Coding ------ * Don't write long functions with a lot of variables and/or scopes - break them down into smaller static functions where possible. This makes code much easier to read and maintain. * Use GLib types and functions - gint not int, g_free() not free(). * Your code should build against GLib 2.32 and GTK 3.24. * Variables should be declared (and initialized) as close as practical to their first use. This reduces the chances of intervening code being inserted between declaration and use, where the variable may be uninitialized. * Variables should be defined within the smallest scope that is practical, for example inside a conditional branch which uses them or in the initialization part of a for loop. * Local variables that will not be modified should be marked as ``const`` to indicate intention. This allows the compiler to give a warning if part of the code accidentally tries to change the value. * Pointer parameters should be marked ``const`` if the value they point to will not be mutated within the function. * Don't let variable names shadow outer variables - use gcc's -Wshadow option. * Use the strictest possible data type where practical. Avoid using untyped pointers (e.g. gpointer) where practical. For an enumeration, use the actual enum type rather than just a ``gint``, use a ``gchar`` for individual (ASCII/UTF-8) string characters rather than ``gint``, and use a ``guint`` for integers which cannot be negative rather than ``gint``. * Prefer loops to calling ``some_type_foreach()`` with a ``user_data`` argument. (Note: Some containers don't support external iteration, e.g. for tree structures, so ``*_foreach`` is fine for those). * Do not use G_LIKELY or G_UNLIKELY (except in critical loops). These add noise to the code with little real benefit. Compiler options & warnings ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use ``CFLAGS='-Wfoo' ./configure`` or ``CFLAGS='-Wfoo' ./autogen.sh`` to set warning options (as well as anything else e.g. -g -O2). * Enable warnings - for gcc use '-Wall -Wextra' (and optionally -Wno-unused-parameter to avoid unused parameter warnings in Glade callbacks). Alternatively you can use the Glib macro G_GNUC_UNUSED to suppress warnings on single parameters, e.g. ``void examplefunction(G_GNUC_UNUSED gchar *foo)``. Also see https://developer.gnome.org/glib/stable/glib-Miscellaneous-Macros.html. * You should try to write ISO C99 code for portability, so always use C ``/* */`` comments and function_name(void) instead of function_name(). This is for compatibility with various Unix-like compilers. You should use -std=c99 to help check this. .. tip:: Remember for gcc you need to enable optimization to get certain warnings like uninitialized variables, but for debugging it's better to have no optimization on. Style ^^^^^ * We use a tab width of 4 and indent completely with tabs not spaces. Note the documentation files use (4) spaces instead, so you may want to use the 'Detect from file' indent pref. * Do not add whitespace at the end of lines, this adds to commit noise. When editing with Geany set preference files->Strip trailing spaces and tabs. * Use the multiline comment ``/* */`` to comment small blocks of code, functions descriptions or longer explanations of code, etc. The more comments are in your code the better. (See also ``scripts/fix-cxx-comments.pl`` in Git). * Lines should not be longer than about 100 characters and after 100 characters the lines should be wrapped and indented once more to show that the line is continued. * We don't put spaces between function names and the opening brace for argument lists. * Variable declarations come first after an opening brace, then one newline to separate declarations and code. * 2-operand operators should have a space each side. * Function bodies should have 2 blank newlines after them. * Align braces together on separate lines. * Don't put assignments in 'if/while/etc' expressions except for loops, for example ``for (int i = 0; i < some_limit; i++)``. * if statements without brace bodies should have the code on a separate line, then a blank line afterwards. * Use braces after if/while statements if the body uses another if/while statement. * Try to fit in with the existing code style. .. note:: A few of the above can be done with the Git ``scripts/fix-alignment.pl``, but it is quite dumb and it's much better to write it correctly in the first place. ``scripts/rstrip-whitespace.py`` just removes trailing whitespace. .. below tabs should be used, but spaces are required for reST. Example:: struct Bar; typedef struct Foo /* struct names normally are the same as typedef names */ { gint foo; /* names are somewhat aligned visually */ gint bar; /* fields don't share the same line */ SomeLongTypeName baz; /* alignment is not strict */ gchar *ptr; /* pointer symbol must go next to variable name, not type */ Bar public; /**< only plugin API fields have a doc-comment */ } Foo; gint some_func(void); gint some_other_func(void); /* optional function comment explains something important */ gint function_long_name(gchar arg1, , gchar argN) { /* variable declarations always go before code in each scope */ /* variable names should NOT be aligned at all */ gint foo, bar; /* variables can go on the same line */ gint baz; /* but often don't */ gchar *ptr; /* pointer symbol must go next to variable name, not type */ gchar *another; /* pointers should normally go on separate lines */ /* Some long comment block * taking several different * lines to explain */ if (foo) { /* variables only used in one scope should normally be declared there */ gint dir = -1; bar = foo; if ((bar & (guint)dir) != 7) some_code(arg1, , argN - 1, argN); some_func(); } } /** Explains using doc-comments for plugin API functions. * First line should be short and use the third person tense - 'explains', * not 'explain'. * * @return Some number. * @since 1.22. */ gint another_function(void) { ... Header Includes --------------- In order to make including various headers in Geany more convenient, each file should include what it uses. If there is a file named ``foo.c``, and a file named ``foo.h``, it should be possible to include ``foo.h`` on its own without depending on stuff in ``foo.c`` that is included for the first time before ``foo.h``. Private Headers ^^^^^^^^^^^^^^^ If there is some data that needs to be shared between various parts of the core code, put them in a "private header", that is, if the public header is called ``foo.h``, then make a ``fooprivate.h`` header that contains the non-public functions, types, globals, etc that are needed. Other core source files can then just include the ``foo.h`` and/or ``fooprivate.h`` depending what they need, without exposing that stuff to plugins. Order of Includes ^^^^^^^^^^^^^^^^^ Inside a source file the includes section should be ordered like this: 1. Always include the ``config.h`` file at the start of every source file, for example:: #ifdef HAVE_CONFIG_H # include "config.h" #endif This allows the Autotools and other build systems use the ``./configure`` time settings. If you don't do this, there's likely to be a number of macros that you'll have to define in the build system or custom headers. Warning: Never include ``config.h`` in headers, and especially in "public" headers that plugins might include. 2. Then include the header that has the same name as the source file (if applicable). For example, for a source file named ``foo.c``, include the ``foo.h`` below the ``config.h`` include. If there is a ``fooprivate.h``, ``foo.c`` will most likely want to include that too, put it in with includes in #3. 3. At this point, it should be safe to include all the headers that declare whatever is needed. If everything generally "includes what it uses" and all files included contain the appropriate multiple-declaration guards then the order of includes is fairly arbitrary. Prefer to use English alphabetic order if possible. 4. By now it doesn't really matter about the order, nothing below here is "our problem". Semi-arbitrarily, you should use an include order like this: 1. Standard C headers 2. Non-standard system headers (eg. ``windows.h`` or ``unistd.h``) 3. GLib/GTK+ or related headers 5. Everything else that should not influence 1-4. Including in Header Files ^^^^^^^^^^^^^^^^^^^^^^^^^ Headers should also include what they use. All of the types should defined in order to allow the header to be included stand-alone. For example, if a header uses a ``GtkWidget*``, it should ``#include ``. Or, if a headers uses a ``GPtrArray*``, it should ``#include `` to ensure that all of the types are declared, whether by pointers/opaquely or fully, as required. Since all headers will use a ``G_BEGIN_DECLS`` and ``G_END_DECLS`` guard for C++, the bare minimum for a header is to include ``glib.h`` or ```` or ``gtkcompat.h`` or some other header that makes those macros available. Committing ---------- * Commit one thing at a time, do small commits. Commits should be meaningful and not too big when possible; multiple small commits are good if there is no good reason to group them. * Use meaningful name and email in the Author and Committer fields. This helps knowing who did what and allows to contact the author if there is a good reason to do so (unlikely, but can happen). * When working on a new feature, create a new branch for it. When merging it, use the --no-ff option to make sure a merge commit will be created to better track what happened. However, if the feature only took one commit you might merge it fast-forward since there is not history to keep together. Commit messages ^^^^^^^^^^^^^^^ Follow the standard Git formatting: * No line should use more than about 80 characters (around 72 is best). * The first line is the commit's summary and is followed by an empty line. This summary should be one line and one line only, thus less than 80 characters. This summary should not include any punctuation unless really needed. See it as the subject of an email: keep it concise and as precise as you can, but not tool long. * Following lines are optional detailed commit information, with paragraphs separated by blank lines. This part should be as long as needed to describe the commit in depth, should use proper punctuation and should include any useful information, like the motivation for the patch and/or any valuable details the diff itself don't provide or don't make clear. Make it as complete as you think it makes sense, but don't include an information that is better explained by the commit's diff. It is OK to use ASCII formatting like bullet list using "*" or "-", etc. if useful, but emphasis (bold, italic, underline) should be avoided. Example:: Ask the user if spawn fails in utils_open_browser() Ask the user to configure a valid browser command if spawning it fails rather than falling back to some arbitrary hardcoded defaults. This avoid spawning an unexpected browser when the configured one is wrong, and gives the user a chance to correctly fix the preference. Testing ------- * Run with ``-v`` to print any debug messages. * You can use a second instance (``geany -i``). * To check first-run behaviour, use an alternate config directory by passing ``-c some_dir`` (but make sure the directory is clean first). * For debugging tips, see `GDB`_. Bugs to watch out for --------------------- * Forgetting to check *doc->is_valid* when looping through *documents_array* - instead use *foreach_document()*. * Inserting fields into structs in the plugin API instead of appending. * Not breaking the plugin ABI when necessary. * Using an idle callback that doesn't check main_status.quitting. * Forgetting CRLF line endings on Windows. * Not handling Tabs & Spaces indent mode. Libraries --------- We try to use an unmodified version of Scintilla - any new lexers or other changes should be passed on to the maintainers at https://scintilla.org. We normally update to a new Scintilla release shortly after one is made. See also scintilla/README. We use an unmodified subset of universal-ctags sources (https://github.com/universal-ctags/ctags) to parse open documents. We also use the great majority of unmodified universal-ctags parsers except a few outliers that are maintained by us (those whose file names start with `geany_`). We normally update to the latest version of universal-ctags shortly after making a Geany release and keep this version during the rest of the development cycle. Notes ===== Some of these notes below are brief (or maybe incomplete) - please contact the geany-devel mailing list for more information. Using pre-defined autotools values ---------------------------------- When you are use macros supplied by the autotools like GEANY_PREFIX, GEANY_LIBDIR, GEANY_DATADIR and GEANY_LOCALEDIR be aware that these might not be static strings when Geany is configured with --enable-binreloc. Then these macros will be replaced by function calls (in src/prefix.h). So, don't use anything like printf("Prefix: " GEANY_PREFIX); but instead use printf("Prefix: %s", GEANY_PREFIX); Adding a source file foo.[hc] in src/ or plugins/ ------------------------------------------------- * Add foo.c, foo.h to SRCS in path/Makefile.am and meson.build. * Add path/foo.c to po/POTFILES.in (for string translation). Adding a filetype ----------------- You can add a filetype without syntax highlighting or tag parsing, but check to see if those features have been written in upstream projects first (scintilla or ctags). **Custom:** If you want to reuse an existing lexer and/or tag parser, making a custom filetype is probably easier - it doesn't require any changes to the source code. Follow instructions in the manual: https://geany.org/manual/index.html#custom-filetypes. Don't forget to update the ``[Groups]`` section in ``filetype_extensions.conf``. .. warning:: You should use the newer `[build-menu]` section for default build commands - the older `[build_settings]` may not work correctly for custom filetypes. **Built-in:** * Add GEANY_FILETYPES_FOO to filetypes.h. * Initialize GEANY_FILETYPES_FOO in init_builtin_filetypes() of filetypes.c. * Update data/filetype_extensions.conf. The remaining notes relate mostly to built-in filetypes. filetypes.* configuration file ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ All languages need a data/filetypes.foo configuration file. See the "Filetype definition files" section in the manual and/or data/filetypes.c for an example. Programming languages should have: * [keywords] if the lexer supports it. * [settings] mostly for comment settings. * [build-menu] (or [build_settings]) for commands to run. For languages with a Scintilla lexer, there should be a [styling] section, to correspond to the styles used in highlighting_styles_FOO[] in highlightingmappings.h - see below. Don't forget to add the newly created filetype file to data/Makefile.am. Syntax highlighting ^^^^^^^^^^^^^^^^^^^ It may be possible to use an existing Scintilla lexer in the scintilla/ subdirectory - if not, you will need to find (or write) one, LexFoo.cxx. Try the official Scintilla project first. .. warning:: We won't accept adding a lexer that conflicts with one in Scintilla. All new lexers should be submitted back to the Scintilla project to save duplication of work. When adding a lexer: * add LexFoo.cxx to scintilla/lexilla/lexers * add `&lmFoo` to scintilla/lexilla/src/Lexilla.cxx and scintilla/scintilla_changes.patch * update scintilla/Makefile.am and meson.build For syntax highlighting, you will need to edit highlighting.c and highlightingmappings.h and add the following things: 1. In highlightingmappings.h: a. define ``highlighting_lexer_FOO`` to the Scintilla lexer ID for this filtype, e.g. ``SCLEX_CPP``. b. define the ``highlighting_styles_FOO`` array that maps Scintilla style states to style names in the configuration file. c. define ``highlighting_keywords_FOO`` to ``EMPTY_KEYWORDS`` if the filtype has no keywords, or as an ``HLKeyword`` array mapping the Scintilla keyword IDs to names in the configuration file. d. define ``highlighting_properties_FOO`` to ``EMPTY_PROPERTIES``, or as an array of ``HLProperty`` if the filetype requires some lexer properties to be set. However, note that properties should normally be set in the ``[lexer_properties]`` section of the configuration file instead. You may look at other filtype's definitions for some examples (Ada, CSS or Diff being good examples). 2. In highlighting.c: a. Add ``init_styleset_case(FOO);`` in ``highlighting_init_styles()``. b. Add ``styleset_case(FOO);`` in ``highlighting_set_styles()``. 3. Write data/filetypes.foo configuration file [styling] section. See the manual and see data/filetypes.d for a named style example. .. note:: Please try to make your styles fit in with the other filetypes' default colors, and to use named styles where possible (e.g. "commentline=comment"). Filetypes that share a lexer should have the same colors. If not using named styles, leave the background color empty to match the default color. Error message parsing ^^^^^^^^^^^^^^^^^^^^^ New-style error message parsing is done with an extended GNU-style regex stored in the filetypes.foo file - see the [build_settings] information in the manual for details. Old-style error message parsing is done in msgwin_parse_compiler_error_line() of msgwindow.c - see the ParseData typedef for more information. Other features ^^^^^^^^^^^^^^ If the lexer has comment styles, you should add them in highlighting_is_comment_style(). You should also update highlighting_is_string_style() for string/character styles. For now, this prevents calltips and autocompletion when typing in a comment (but it can still be forced by the user). For brace indentation, update lexer_has_braces() in editor.c; indentation after ':' is done from on_new_line_added(). If the Scintilla lexer supports user type keyword highlighting (e.g. SCLEX_CPP), update document_update_tags() in document.c. Adding a CTags parser ^^^^^^^^^^^^^^^^^^^^^ This assumes the filetype for Geany already exists. First write or find a CTags compatible parser, foo.c. Check this fork: https://github.com/universal-ctags/ctags Method `````` * Add foo.c to SRCS in Makefile.am and meson.build. * Add Foo to src/tagmanager/tm_parsers.h * Add TM_PARSER_FOO to src/tagmanager/tm_parser.h. The list here must follow exactly the order in src/tagmanager/tm_parsers.h. In src/tagmanager/tm_parser.c: Add a map_FOO TMParserMapEntry mapping each kind's letter from foo.c's FooKinds to the appropriate TMTagType, and add the corresponding MAP_ENTRY(FOO) to parser_map. In src/tagmanager/tm_parser.c: Add a group_FOO TMParserMapGroup defining root nodes of the symbol tree, used icons and TMTagType values grouped under the specified root. Multiple TMTagType values can be combined under a single root using | (bitwise OR). In src/tagmanager/tm_parser.c: Update various functions at the end of tm_parser.c to adjust Geany behavior to the behavior of the added parser. In particular, update tm_parser_scope_separator() and tm_parser_has_full_scope() so scope-related functionality works correctly. In filetypes.c, init_builtin_filetypes(): Set the 2nd argument of the FT_INIT() macro for this filetype to FOO. Tests ````` The tag parser tests checks if the proper tags are emitted for a given source. Tests for tag parsers consist of two files: the source to parse, and the expected output. Tests are run using ``make check``. The source to parse should be in the file ``tests/ctags/mytest.ext``, where ``mytest`` is the name you choose for your test, and ``ext`` is an extension recognized by Geany as the language the test file is for. This file should contain a snippet of the language to test for. It can be either long or short, depending on what it tests. The expected output should be in the file ``tests/ctags/mytest.ext.tags`` (which is the same name as the source, but with ``.tags`` appended), and should be in the format generated by:: $ geany -g tmp.ext.tags tests/ctags/mytest.ext $ scripts/print-tags.py < tmp.ext.tags > tests/ctags/mytest.ext.tags This file contains the tag information expected to be generated from the corresponding source file together with its human-readable form. When you have these two files, you have to list your new test along the other ones in the ``test_source`` variable in ``tests/ctags/Makefile.am`` and ``tests/meson.build``. Please keep this list sorted alphabetically. Upgrading Scintilla ------------------- To upgrade the local Scintilla copy, use the ``scripts/update-scintilla.sh`` script. To use it, you need to first obtain a copy of the Scintilla sources you want to update to. This will generally mean checking out a release tag from the Scintilla Mercurial repository, or extracting a tarball. Then, just run the script from Geany's to source directory passing the path to the Scintilla source directory as first argument, and follow the instructions, if any:: ./scripts/update-scintilla.sh /path/to/scintilla/ GDB --- Stop on warnings ^^^^^^^^^^^^^^^^ When a GLib or GTK warning is printed, often you want to get a backtrace to find out what code caused them. You can do that with the ``--g-fatal-warnings`` argument, which will abort Geany on the first warning it receives. But for ordinary testing, you don't always want your editor to abort just because of a warning - use:: (gdb) b handler_log if level <= G_LOG_LEVEL_WARNING Running with batch commands ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use:: $ gdb src/geany -x gdb-commands Where ``gdb-commands`` is a file with the following lines:: set pagination off b handler_log if level <= G_LOG_LEVEL_WARNING r -v Loading a plugin ^^^^^^^^^^^^^^^^ This is useful so you can load plugins without installing them first. Alternatively you can use a symlink in ~/.config/geany/plugins or $prefix/lib/geany (where $prefix is /usr/local by default). The gdb session below was run from the toplevel Geany source directory. Start normally with e.g. "gdb src/geany". Type 'r' to run. Press Ctrl-C from the gdb window to interrupt program execution. Example:: Program received signal SIGINT, Interrupt. 0x00d16402 in __kernel_vsyscall () (gdb) call plugin_new("./plugins/.libs/demoplugin.so") ** INFO: Loaded: ./plugins/.libs/demoplugin.so (Demo) $1 = (Plugin *) 0x905a890 (gdb) c Continuing. Program received signal SIGINT, Interrupt. 0x00d16402 in __kernel_vsyscall () (gdb) call plugin_free(0x905a890) ** INFO: Unloaded: ./plugins/.libs/demoplugin.so (gdb) c Continuing. Building Plugins ^^^^^^^^^^^^^^^^ The geany-plugins autotools script automatically detects the installed system Geany and builds the plugins against that. To use plugins with a development version of Geany built with a different prefix, the plugins will need to be compiled against that version if the ABI has changed. To do this you need to specify both --prefix and --with-geany-libdir to the plugin configure. Normally the plugin prefix is the same as the Geany prefix to keep plugins with the version of Geany that they are compiled against, and with-geany-libdir is the Geany prefix/lib. Whilst it is possible for the plugin prefix to be different to the prefix of the libdir (which is why there are two settings), it is probably better to keep the version of Geany and its plugins together. geany-2.0/README.I18N0000644000175000017500000000705214514252267010751 00000000000000Quick Guide for new translations -------------------------------- If you would like to translate Geany into another language, have a look at the language statistics page at [1] first to see if your desired language already exists. If it already exists, please read the "Notes for updating translations" section. Otherwise, get the Git version of Geany, change to the po directory and start the new translation with: $ msginit -l ll_CC -o ll.po -i geany.pot Fill in ll with the language code and CC with the country code. For example, to translate Geany into Italian you would type: $ msginit -l it_IT -o it.po -i geany.pot This will create a file it.po. This file can be opened with a text editor (e.g. Geany ;-)) or a graphical program like PoEdit [2]. There are also several other GUI programs for working on translations. You don't need to modify the file po/LINGUAS, it is regenerated automatically on the next build. When you have finished editing the file, check the file with: $ msgfmt -c --check-accelerators=_ it.po Please ensure you also translate the mnemonic letters (strings containing a "_" before a letter, also called "accelerators" on some platforms/toolkits). When the user wishes to activate a menu item using their keyboard, they will use this letter to pick an item from the menu. Here are a few notes on picking which letter to use: * Always follow platform/toolkit conventions (for example "t" for "Cut") even if they don't necessarily seem obvious. * Try to choose the first letter of the command name, where this is the most appropriate letter (for example "S" for "Save"), assuming it's not already used in the same menu. * Try not to use the same character more than once in the same menu as this will cause the user to have to press the mnemonic's key multiple times to select the correct menu item. * If there is no letter in the text that can easily be entered from a keyboard then choose another character that can be, and put it in parenthesis after the translated text. * Try not to change which letter is used whenever possible as it is not user-configurable and users may have become accustomed to using the existing mnemonic key. You can also use intl_stats.sh, e.g. by running the following command in the top source directory of Geany: $ po/intl_stats.sh -a it This will print some information about the Italian translation and checks for menu accelerators. When you have finished your work - which doesn't mean you finished the translation, you will not have to work alone - send the file to the translation mailing list [3] or directly to Frank Lanitz [4] and he will add the translation to Geany then. It is a good idea to let any translator and Frank know before you start or while translating, because they can give you hints on translating and Frank can ensure that a translation is not already in progress. Notes for updating translations ------------------------------- If you want to update an existing translation, please contact the translation mailing list [3] and/or Frank Lanitz [4] directly. He is supervising all translation issues and will contact the maintainer of the translation you want to update to avoid any conflicts. Some translation statistics can be found at: https://i18n.geany.org/ I18n mailing list ----------------- There is also a mailing list dedicated to translation issues. Please visit https://www.geany.org/Support/MailingList#geany-i18 for more information. [1] https://i18n.geany.org/ [2] https://www.poedit.net/ [3] https://www.geany.org/support/mailing-lists/#geany-i18n [4] Frank Lanitz geany-2.0/Makefile.am0000644000175000017500000000467214514252267011454 00000000000000## Process this file with automake to produce Makefile.in SUBDIRS = ctags scintilla src plugins icons po doc data tests AUTOMAKE_OPTIONS = 1.7 ACLOCAL_AMFLAGS = -I m4 AM_DISTCHECK_CONFIGURE_FLAGS = --enable-api-docs --enable-html-docs --enable-pdf-docs \ --enable-gtkdoc-header WIN32_BUILD_FILES = \ geany_private.rc \ geany.exe.manifest EXTRA_DIST = \ autogen.sh \ scripts/gen-api-gtkdoc.py \ scripts/gen-signallist.sh \ scripts/print-tags.py \ geany.desktop.in \ geany.pc.in \ ChangeLog.pre-1-22 \ HACKING \ README.I18N \ README.Packagers \ $(WIN32_BUILD_FILES) DISTCLEANFILES = \ geany.desktop uninstall-local: rm -rf $(DESTDIR)$(pkgdatadir); # manually install some files under another name install-data-local: $(mkinstalldirs) $(DESTDIR)$(pkgdatadir) $(INSTALL_DATA) $(srcdir)/COPYING $(DESTDIR)$(pkgdatadir)/GPL-2 if MINGW $(INSTALL_DATA) $(srcdir)/AUTHORS $(DESTDIR)$(prefix)/Authors.txt $(INSTALL_DATA) $(srcdir)/ChangeLog $(DESTDIR)$(prefix)/Changelog.txt $(INSTALL_DATA) $(srcdir)/COPYING $(DESTDIR)$(prefix)/Copying.txt $(INSTALL_DATA) $(srcdir)/README $(DESTDIR)$(prefix)/Readme.txt $(INSTALL_DATA) $(srcdir)/NEWS $(DESTDIR)$(prefix)/News.txt $(INSTALL_DATA) $(srcdir)/THANKS $(DESTDIR)$(prefix)/Thanks.txt $(INSTALL_DATA) $(srcdir)/TODO $(DESTDIR)$(prefix)/Todo.txt endif dist-hook: @if test -d "$(top_srcdir)/.git"; then \ echo ' GEN ChangeLog'; \ ( cd "$(top_srcdir)" && \ echo '# Generated by Makefile. Do not edit.' && echo && \ GIT_CONFIG_NOSYSTEM=1 HOME="$(srcdir)" XDG_CONFIG_HOME="$(srcdir)" \ git log --stat 0.21.0.. ) > ChangeLog.tmp \ && mv -f ChangeLog.tmp "$(distdir)/ChangeLog" \ || ( rm -f ChangeLog.tmp ; \ echo 'Failed to generate ChangeLog' >&2 ); \ else \ echo 'A git clone is required to generate a ChangeLog' >&2; \ fi sign: if test -f $(PACKAGE)-$(VERSION).tar.gz; then \ gpg --detach-sign --digest-algo SHA512 $(PACKAGE)-$(VERSION).tar.gz; fi if test -f $(PACKAGE)-$(VERSION).tar.bz2; then \ gpg --detach-sign --digest-algo SHA512 $(PACKAGE)-$(VERSION).tar.bz2; fi rpm: dist rpmbuild -ta $(distdir).tar.gz pkgconfig_DATA = geany.pc pkgconfigdir = $(libdir)/pkgconfig desktopdir = $(datadir)/applications desktop_in_files = geany.desktop.in desktop_DATA = $(desktop_in_files:.desktop.in=.desktop) $(desktop_DATA): $(desktop_in_files) $(wildcard $(top_srcdir)/po/*.po) $(AM_V_GEN)$(MSGFMT) --desktop --template $< -d $(top_srcdir)/po -o $@ geany-2.0/src/0000755000175000017500000000000014514253233010250 500000000000000geany-2.0/src/main.c0000644000175000017500000000202114514252267011261 00000000000000/* * main.c - this file is part of Geany, a fast and lightweight IDE * * Copyright 2005 The Geany contributors * * This program 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; either version 2 of the License, or * (at your option) any later version. * * This program 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /* See libmain.c for the real entry-point code. */ #include "main.h" int main(int argc, char **argv) { return main_lib(argc, argv); } geany-2.0/src/win32.h0000644000175000017500000000336014514252267011313 00000000000000/* * win32.h - this file is part of Geany, a fast and lightweight IDE * * Copyright 2005 The Geany contributors * * This program 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; either version 2 of the License, or * (at your option) any later version. * * This program 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef GEANY_WIN32_H #define GEANY_WIN32_H 1 #include "document.h" #include "gtkcompat.h" #ifdef G_OS_WIN32 G_BEGIN_DECLS gchar *win32_show_file_dialog(GtkWindow *parent, const gchar *title, const gchar *initial_dir); gboolean win32_message_dialog(GtkWidget *parent, GtkMessageType type, const gchar *msg); void win32_open_browser(const gchar *uri); gchar *win32_show_folder_dialog(GtkWidget *parent, const gchar *title, const gchar *initial_dir); gint win32_check_write_permission(const gchar *dir); void win32_init_debug_code(void); void win32_set_working_directory(const gchar *dir); gchar *win32_get_shortcut_target(const gchar *file_name); gchar *win32_get_installation_dir(void); gchar *win32_expand_environment_variables(const gchar *str); gchar *win32_get_user_config_dir(void); G_END_DECLS #endif /* G_OS_WIN32 */ #endif /* GEANY_WIN32_H */ geany-2.0/src/about.h0000644000175000017500000000204214514252267011457 00000000000000/* * about.h - this file is part of Geany, a fast and lightweight IDE * * Copyright 2005 The Geany contributors * * This program 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; either version 2 of the License, or * (at your option) any later version. * * This program 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef GEANY_ABOUT_H #define GEANY_ABOUT_H 1 #include G_BEGIN_DECLS void about_dialog_show(void); G_END_DECLS #endif /* GEANY_ABOUT_H */ geany-2.0/src/plugindata.h0000644000175000017500000003706514514252267012512 00000000000000/* * plugindata.h - this file is part of Geany, a fast and lightweight IDE * * Copyright 2007 The Geany contributors * * This program 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; either version 2 of the License, or * (at your option) any later version. * * This program 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /** * @file plugindata.h * This file defines the plugin API, the interface between Geany and its plugins. * For detailed documentation of the plugin system please read the plugin * API documentation. **/ /* Note: Remember to increment GEANY_API_VERSION (and GEANY_ABI_VERSION if necessary) * when making changes (see 'Keeping the plugin ABI stable' in the HACKING file). */ #ifndef GEANY_PLUGIN_DATA_H #define GEANY_PLUGIN_DATA_H 1 #include "build.h" /* GeanyBuildGroup, GeanyBuildSource, GeanyBuildCmdEntries enums */ #include "document.h" /* GeanyDocument */ #include "editor.h" /* GeanyEditor, GeanyIndentType */ #include "filetypes.h" /* GeanyFiletype */ #include "gtkcompat.h" G_BEGIN_DECLS /* Compatibility for sharing macros between API and core. * First include geany.h, then plugindata.h, then other API headers. */ #undef GEANY #define GEANY(symbol_name) geany->symbol_name /** The Application Programming Interface (API) version, incremented * whenever any plugin data types are modified or appended to. * * You can protect code that needs a higher API than e.g. 200 with: * @code #if GEANY_API_VERSION >= 200 * some_newer_function(); * #endif @endcode * * @warning You should not test for values below 200 as previously * @c GEANY_API_VERSION was defined as an enum value, not a macro. */ #define GEANY_API_VERSION 247 /* hack to have a different ABI when built with different GTK major versions * because loading plugins linked to a different one leads to crashes. * Only GTK3 is currently supported. */ #define GEANY_ABI_SHIFT 8 /** The Application Binary Interface (ABI) version, incremented whenever * existing fields in the plugin data types have to be changed or reordered. * Changing this forces all plugins to be recompiled before Geany can load them. */ /* This should usually stay the same if fields are only appended, assuming only pointers to * structs and not structs themselves are declared by plugins. */ #define GEANY_ABI_VERSION (73 << GEANY_ABI_SHIFT) /** Defines a function to check the plugin is safe to load. * This performs runtime checks that try to ensure: * - Geany ABI data types are compatible with this plugin. * - Geany sources provide the required API for this plugin. * @param api_required The minimum API number your plugin requires. * Look at the source for the value of @c GEANY_API_VERSION to use if you * want your plugin to require the current Geany version on your machine. * You should update this value when using any new API features. */ #define PLUGIN_VERSION_CHECK(api_required) \ gint plugin_version_check(gint abi_ver) \ { \ if (abi_ver != GEANY_ABI_VERSION) \ return -1; \ return (api_required); \ } /** Basic information about a plugin available to Geany without loading the plugin. * The fields are set in plugin_set_info(), usually with the PLUGIN_SET_INFO() macro. */ typedef struct PluginInfo { /** The name of the plugin. */ const gchar *name; /** The description of the plugin. */ const gchar *description; /** The version of the plugin. */ const gchar *version; /** The author of the plugin. */ const gchar *author; } PluginInfo; /** Sets the plugin name and some other basic information about a plugin. * * @note If you want some of the arguments to be translated, see @ref PLUGIN_SET_TRANSLATABLE_INFO() * * Example: * @code PLUGIN_SET_INFO("Cool Feature", "Adds cool feature support.", "0.1", "Joe Author") @endcode */ /* plugin_set_info() could be written manually for plugins if we want to add any * extra PluginInfo features (such as an icon), so we don't need to break API * compatibility. Alternatively just add a new macro, PLUGIN_SET_INFO_FULL(). -ntrel */ #define PLUGIN_SET_INFO(p_name, p_description, p_version, p_author) \ void plugin_set_info(PluginInfo *info) \ { \ info->name = (p_name); \ info->description = (p_description); \ info->version = (p_version); \ info->author = (p_author); \ } /** Sets the plugin name and some other basic information about a plugin. * This macro is like @ref PLUGIN_SET_INFO() but allows the passed information to be translated * by setting up the translation mechanism with @ref main_locale_init(). * You therefore don't need to call it manually in plugin_init(). * * Example: * @code PLUGIN_SET_TRANSLATABLE_INFO(LOCALEDIR, GETTEXT_PACKAGE, _("Cool Feature"), _("Adds a cool feature."), "0.1", "John Doe") @endcode * * @since 0.19 */ #define PLUGIN_SET_TRANSLATABLE_INFO(localedir, package, p_name, p_description, p_version, p_author) \ void plugin_set_info(PluginInfo *info) \ { \ main_locale_init((localedir), (package)); \ info->name = (p_name); \ info->description = (p_description); \ info->version = (p_version); \ info->author = (p_author); \ } /** Callback array entry type used with the @ref plugin_callbacks symbol. */ typedef struct PluginCallback { /** The name of signal, must be an existing signal. For a list of available signals, * please see the @link pluginsignals.c Signal documentation @endlink. */ const gchar *signal_name; /** A callback function which is called when the signal is emitted. */ GCallback callback; /** Set to TRUE to connect your handler with g_signal_connect_after(). */ gboolean after; /** The user data passed to the signal handler. If set to NULL then the signal * handler will receive the data set with geany_plugin_register_full() or * geany_plugin_set_data() */ gpointer user_data; } PluginCallback; /** This contains pointers to global variables owned by Geany for plugins to use. * Core variable pointers can be appended when needed by plugin authors, if appropriate. */ typedef struct GeanyData { struct GeanyApp *app; /**< Geany application data fields */ struct GeanyMainWidgets *main_widgets; /**< Important widgets in the main window */ /** Dynamic array of GeanyDocument pointers. * Once a pointer is added to this, it is never freed. This means the same document pointer * can represent a different document later on, or it may have been closed and become invalid. * For this reason, you should use document_find_by_id() instead of storing * document pointers over time if there is a chance the user can close the * document. * * @warning You must check @c GeanyDocument::is_valid when iterating over this array. * This is done automatically if you use the foreach_document() macro. * * @note * Never assume that the order of document pointers is the same as the order of notebook tabs. * One reason is that notebook tabs can be reordered. * Use @c document_get_from_page() to lookup a document from a notebook tab number. * * @see documents. * * @elementtype{GeanyDocument} */ GPtrArray *documents_array; /** Dynamic array of filetype pointers * * List the list is dynamically expanded for custom filetypes filetypes so don't expect * the list of known filetypes to be a constant. * * @elementtype{GeanyFiletype} */ GPtrArray *filetypes_array; struct GeanyPrefs *prefs; /**< General settings */ struct GeanyInterfacePrefs *interface_prefs; /**< Interface settings */ struct GeanyToolbarPrefs *toolbar_prefs; /**< Toolbar settings */ struct GeanyEditorPrefs *editor_prefs; /**< Editor settings */ struct GeanyFilePrefs *file_prefs; /**< File-related settings */ struct GeanySearchPrefs *search_prefs; /**< Search-related settings */ struct GeanyToolPrefs *tool_prefs; /**< Tool settings */ struct GeanyTemplatePrefs *template_prefs; /**< Template settings */ gpointer *_compat; /* Remove field on next ABI break (abi-todo) */ /** List of filetype pointers sorted by name, but with @c filetypes_index(GEANY_FILETYPES_NONE) * first, as this is usually treated specially. * The list does not change (after filetypes have been initialized), so you can use * @code g_slist_nth_data(filetypes_by_title, n) @endcode and expect the same result at different times. * @see filetypes_get_sorted_by_name(). * * @elementtype{GeanyFiletype} */ GSList *filetypes_by_title; /** @gironly * Global object signalling events via signals * * This is mostly for language bindings. Otherwise prefer to use * plugin_signal_connect() instead this which adds automatic cleanup. */ GObject *object; } GeanyData; #define geany geany_data /**< Simple macro for @c geany_data that reduces typing. */ typedef struct GeanyPluginFuncs GeanyPluginFuncs; typedef struct GeanyProxyFuncs GeanyProxyFuncs; /** Basic information for the plugin and identification. * @see geany_plugin. */ typedef struct GeanyPlugin { PluginInfo *info; /**< Fields set in plugin_set_info(). */ GeanyData *geany_data; /**< Pointer to global GeanyData intance */ GeanyPluginFuncs *funcs; /**< Functions implemented by the plugin, set in geany_load_module() */ GeanyProxyFuncs *proxy_funcs; /**< Hooks implemented by the plugin if it wants to act as a proxy Must be set prior to calling geany_plugin_register_proxy() */ struct GeanyPluginPrivate *priv; /* private */ } GeanyPlugin; #ifndef GEANY_PRIVATE /* Prototypes for building plugins with -Wmissing-prototypes * Also allows the compiler to check if the signature of the plugin's * symbol properly matches what we expect. */ gint plugin_version_check(gint abi_ver); void plugin_set_info(PluginInfo *info); void plugin_init(GeanyData *data); GtkWidget *plugin_configure(GtkDialog *dialog); void plugin_configure_single(GtkWidget *parent); void plugin_help(void); void plugin_cleanup(void); /** Called by Geany when a plugin library is loaded. * * This is the original entry point. Implement and export this function to be loadable at all. * Then fill in GeanyPlugin::info and GeanyPlugin::funcs of the passed @p plugin. Finally * GEANY_PLUGIN_REGISTER() and specify a minimum supported API version. * * For all glory details please read @ref howto. * * Because the plugin is not yet enabled by the user you may not call plugin API functions inside * this function, except for the API functions below which are required for proper registration. * * API functions which are allowed to be called within this function: * - main_locale_init() * - geany_plugin_register() (and GEANY_PLUGIN_REGISTER()) * - geany_plugin_register_full() (and GEANY_PLUGIN_REGISTER_FULL()) * - plugin_module_make_resident() * * @param plugin The unique plugin handle to your plugin. You must set some fields here. * * @since 1.26 (API 225) * @see @ref howto */ void geany_load_module(GeanyPlugin *plugin); #endif /** Callback functions that need to be implemented for every plugin. * * These callbacks should be registered by the plugin within Geany's call to * geany_load_module() by calling geany_plugin_register() with an instance of this type. * * Geany will then call the callbacks at appropriate times. Each gets passed the * plugin-defined data pointer as well as the corresponding GeanyPlugin instance * pointer. * * @since 1.26 (API 225) * @see @ref howto **/ struct GeanyPluginFuncs { /** Array of plugin-provided signal handlers @see PluginCallback */ PluginCallback *callbacks; /** Called to initialize the plugin, when the user activates it (must not be @c NULL) */ gboolean (*init) (GeanyPlugin *plugin, gpointer pdata); /** plugins configure dialog, optional (can be @c NULL) */ GtkWidget* (*configure) (GeanyPlugin *plugin, GtkDialog *dialog, gpointer pdata); /** Called when the plugin should show some help, optional (can be @c NULL) */ void (*help) (GeanyPlugin *plugin, gpointer pdata); /** Called when the plugin is disabled or when Geany exits (must not be @c NULL) */ void (*cleanup) (GeanyPlugin *plugin, gpointer pdata); }; gboolean geany_plugin_register(GeanyPlugin *plugin, gint api_version, gint min_api_version, gint abi_version); gboolean geany_plugin_register_full(GeanyPlugin *plugin, gint api_version, gint min_api_version, gint abi_version, gpointer data, GDestroyNotify free_func); gpointer geany_plugin_get_data(const GeanyPlugin *plugin); void geany_plugin_set_data(GeanyPlugin *plugin, gpointer data, GDestroyNotify free_func); /** Convenience macro to register a plugin. * * It simply calls geany_plugin_register() with GEANY_API_VERSION and GEANY_ABI_VERSION. * * @since 1.26 (API 225) * @see @ref howto **/ #define GEANY_PLUGIN_REGISTER(plugin, min_api_version) \ geany_plugin_register((plugin), GEANY_API_VERSION, \ (min_api_version), GEANY_ABI_VERSION) /** Convenience macro to register a plugin with data. * * It simply calls geany_plugin_register_full() with GEANY_API_VERSION and GEANY_ABI_VERSION. * * @since 1.26 (API 225) * @see @ref howto **/ #define GEANY_PLUGIN_REGISTER_FULL(plugin, min_api_version, pdata, free_func) \ geany_plugin_register_full((plugin), GEANY_API_VERSION, \ (min_api_version), GEANY_ABI_VERSION, (pdata), (free_func)) /** Return values for GeanyProxyHooks::probe() * * @see geany_plugin_register_proxy() for a full description of the proxy plugin mechanisms. */ typedef enum { /** The proxy is not responsible at all, and Geany or other plugins are free * to probe it. * * @since 1.29 (API 229) **/ GEANY_PROXY_IGNORE, /** The proxy is responsible for this file, and creates a plugin for it. * * @since 1.29 (API 229) */ GEANY_PROXY_MATCH, /** The proxy is does not directly load it, but it's still tied to the proxy. * * This is for plugins that come in multiple files where only one of these * files is relevant for the plugin creation (for the PM dialog). The other * files should be ignored by Geany and other proxies. Example: libpeas has * a .plugin and a .so per plugin. Geany should not process the .so file * if there is a corresponding .plugin. * * @since 1.29 (API 229) */ GEANY_PROXY_RELATED = GEANY_PROXY_MATCH | 0x100 } GeanyProxyProbeResults; /** Hooks that need to be implemented by every proxy * * @see geany_plugin_register_proxy() for a full description of the proxy mechanism. * * @since 1.26 (API 226) **/ struct GeanyProxyFuncs { /** Called to determine whether the proxy is truly responsible for the requested plugin. * A NULL pointer assumes the probe() function would always return @ref GEANY_PROXY_MATCH */ gint (*probe) (GeanyPlugin *proxy, const gchar *filename, gpointer pdata); /** Called after probe(), to perform the actual job of loading the plugin */ gpointer (*load) (GeanyPlugin *proxy, GeanyPlugin *subplugin, const gchar *filename, gpointer pdata); /** Called when the user initiates unloading of a plugin, e.g. on Geany exit */ void (*unload) (GeanyPlugin *proxy, GeanyPlugin *subplugin, gpointer load_data, gpointer pdata); }; gint geany_plugin_register_proxy(GeanyPlugin *plugin, const gchar **extensions); G_END_DECLS #endif /* GEANY_PLUGIN_DATA_H */ geany-2.0/src/geanyobject.h0000644000175000017500000000503214514252267012641 00000000000000/* * geanyobject.h - this file is part of Geany, a fast and lightweight IDE * * Copyright 2007 The Geany contributors * * This program 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; either version 2 of the License, or * (at your option) any later version. * * This program 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef GEANY_OBJECT_H #define GEANY_OBJECT_H 1 #include "document.h" #include "editor.h" #include "filetypes.h" #include "Scintilla.h" #include "gtkcompat.h" G_BEGIN_DECLS typedef enum { GCB_DOCUMENT_NEW, GCB_DOCUMENT_OPEN, GCB_DOCUMENT_RELOAD, GCB_DOCUMENT_BEFORE_SAVE, GCB_DOCUMENT_SAVE, GCB_DOCUMENT_FILETYPE_SET, GCB_DOCUMENT_ACTIVATE, GCB_DOCUMENT_CLOSE, GCB_PROJECT_OPEN, GCB_PROJECT_SAVE, GCB_PROJECT_CLOSE, GCB_PROJECT_BEFORE_CLOSE, GCB_PROJECT_DIALOG_OPEN, GCB_PROJECT_DIALOG_CONFIRMED, GCB_PROJECT_DIALOG_CLOSE, GCB_UPDATE_EDITOR_MENU, GCB_EDITOR_NOTIFY, GCB_GEANY_STARTUP_COMPLETE, GCB_BUILD_START, GCB_SAVE_SETTINGS, GCB_LOAD_SETTINGS, GCB_KEY_PRESS_NOTIFY, GCB_MAX } GeanyCallbackId; #define GEANY_OBJECT_TYPE (geany_object_get_type()) #define GEANY_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),\ GEANY_OBJECT_TYPE, GeanyObject)) #define GEANY_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),\ GEANY_OBJECT_TYPE, GeanyObjectClass)) #define IS_GEANY_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),\ GEANY_OBJECT_TYPE)) #define IS_GEANY_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),\ GEANY_OBJECT_TYPE)) typedef struct _GeanyObject GeanyObject; typedef struct _GeanyObjectClass GeanyObjectClass; /** @gironly * Instance structure for GeanyObject */ struct _GeanyObject { GObject parent; /* add your public declarations here */ }; extern GObject *geany_object; /** @gironly * Class structure for @a GeanyObject */ struct _GeanyObjectClass { GObjectClass parent_class; }; GType geany_object_get_type (void); GObject* geany_object_new (void); G_END_DECLS #endif /* GEANY_OBJECT_H */ geany-2.0/src/support.h0000644000175000017500000000301614514252267012063 00000000000000/* * support.h - this file is part of Geany, a fast and lightweight IDE * * Copyright 2006 The Geany contributors * * This program 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; either version 2 of the License, or * (at your option) any later version. * * This program 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /** * @file support.h * Defines internationalization macros. * @see GLib's @c gi18n-lib.h. **/ #ifndef GEANY_SUPPORT_H #define GEANY_SUPPORT_H 1 #include G_BEGIN_DECLS #ifdef GETTEXT_PACKAGE # include #else # define GETTEXT_PACKAGE NULL # define textdomain(String) (String) # define bind_textdomain_codeset(Domain,Codeset) (Codeset) # define bindtextdomain(Domain,Dir) (Dir) # define ngettext(String,PluralString,Number) (((Number) == 1) ? (String) : (PluralString)) # define _(String) String # define N_(String) String # define C_(Context,String) (String) #endif G_END_DECLS #endif /* GEANY_SUPPORT_H */ geany-2.0/src/spawn.c0000644000175000017500000013123714514252267011501 00000000000000/* * spawn.c - this file is part of Geany, a fast and lightweight IDE * * Copyright 2013 The Geany contributors * * This program 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; either version 2 of the License, or * (at your option) any later version. * * This program 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /* An ongoing effort to improve the tool spawning situation under Windows. * In particular: * - There is no g_shell_parse_argv() for windows. It's not hard to write one, * but the command line recreated by mscvrt may be wrong. * - GLib converts the argument vector to UNICODE. For non-UTF8 arguments, * the result is often "Invalid string in argument vector at %d: %s: Invalid * byte sequence in conversion input" (YMMV). Our tools (make, grep, gcc, ...) * are "ANSI", so converting to UNICODE and then back only causes problems. * - For various reasons, GLib uses an intermediate program to start children * (see gspawn-win32.c), the result being that the grandchildren output (such * as make -> gcc) is not captured. * - With non-blocking pipes, the g_io_add_watch() callbacks are never invoked, * while with blocking pipes, g_io_channel_read_line() blocks. * - Some other problems are explained in separate comments below. * * Even under Unix, using g_io_channel_read_line() is not a good idea, since it may * buffer lines of unlimited length. * * This module does not depend on Geany when compiled for testing (-DSPAWN_TEST). */ /** @file spawn.h * Portable and convenient process spawning and communication. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include #include #include "spawn.h" #ifdef G_OS_WIN32 # include /* isspace() */ # include /* _O_RDONLY, _O_WRONLY */ # include /* _open_osfhandle, _close */ # include #else /* G_OS_WIN32 */ # include #endif /* G_OS_WIN32 */ #ifdef SPAWN_TEST # define _ # define GEANY_API_SYMBOL # define geany_debug g_debug #else # include "support.h" # include "geany.h" #endif #if ! GLIB_CHECK_VERSION(2, 31, 20) && ! defined(G_SPAWN_ERROR_TOO_BIG) # define G_SPAWN_ERROR_TOO_BIG G_SPAWN_ERROR_2BIG #endif #ifdef G_OS_WIN32 /* Each 4KB under Windows seem to come in 2 portions, so 2K + 2K is more balanced than 4095 + 1. May be different on the latest Windows/glib? */ # define DEFAULT_IO_LENGTH 2048 #else # define DEFAULT_IO_LENGTH 4096 /* helper function that cuts glib citing of the original text on bad quoting: it may be long, and only the caller knows whether it's UTF-8. Thought we lose the ' or " failed info. */ static gboolean spawn_parse_argv(const gchar *command_line, gint *argcp, gchar ***argvp, GError **error) { GError *gerror = NULL; if (g_shell_parse_argv(command_line, argcp, argvp, &gerror)) return TRUE; g_set_error_literal(error, gerror->domain, gerror->code, gerror->code == G_SHELL_ERROR_BAD_QUOTING ? _("Text ended before matching quote was found") : gerror->message); g_error_free(gerror); return FALSE; } #endif #define SPAWN_IO_FAILURE (G_IO_ERR | G_IO_HUP | G_IO_NVAL) /* always used together */ /* * Checks whether a command line is syntactically valid and extracts the program name from it. * * See @c spawn_check_command() for details. * * @param command_line the command line to check and get the program name from. * @param error return location for error. * * @return allocated string with the program name on success, @c NULL on error. */ static gchar *spawn_get_program_name(const gchar *command_line, GError **error) { gchar *program; #ifdef G_OS_WIN32 gboolean open_quote = FALSE; const gchar *s, *arguments; g_return_val_if_fail(command_line != NULL, FALSE); while (*command_line && strchr(" \t\r\n", *command_line)) command_line++; if (!*command_line) { g_set_error_literal(error, G_SHELL_ERROR, G_SHELL_ERROR_EMPTY_STRING, /* TL note: from glib */ _("Text was empty (or contained only whitespace)")); return FALSE; } /* To prevent Windows from doing something weird, we want to be 100% sure that the character after the program name is a delimiter, so we allow space and tab only. */ if (*command_line == '"') { command_line++; /* Windows allows "foo.exe, but we may have extra arguments */ if ((s = strchr(command_line, '"')) == NULL) { g_set_error_literal(error, G_SHELL_ERROR, G_SHELL_ERROR_BAD_QUOTING, _("Text ended before matching quote was found")); return FALSE; } if (!strchr(" \t", s[1])) /* strchr() catches s[1] == '\0' */ { g_set_error_literal(error, G_SHELL_ERROR, G_SHELL_ERROR_BAD_QUOTING, _("A quoted Windows program name must be entirely inside the quotes")); return FALSE; } } else { const gchar *quote = strchr(command_line, '"'); /* strchr() catches *s == '\0', and the for body is empty */ for (s = command_line; !strchr(" \t", *s); s++); if (quote && quote < s) { g_set_error_literal(error, G_SHELL_ERROR, G_SHELL_ERROR_BAD_QUOTING, _("A quoted Windows program name must be entirely inside the quotes")); return FALSE; } } program = g_strndup(command_line, s - command_line); arguments = s + (*s == '"'); for (s = arguments; *s; s++) { if (*s == '"') { const char *slash; for (slash = s; slash > arguments && slash[-1] == '\\'; slash--); if ((s - slash) % 2 == 0) open_quote ^= TRUE; } } if (open_quote) { g_set_error_literal(error, G_SHELL_ERROR, G_SHELL_ERROR_BAD_QUOTING, _("Text ended before matching quote was found")); g_free(program); return FALSE; } #else /* G_OS_WIN32 */ int argc; char **argv; if (!spawn_parse_argv(command_line, &argc, &argv, error)) return FALSE; /* empty string results in parse error, so argv[0] is not NULL */ program = g_strdup(argv[0]); g_strfreev(argv); #endif /* G_OS_WIN32 */ return program; } /** * Checks whether a command line is valid. * * Checks if @a command_line is syntactically valid. * * All OS: * - any leading spaces, tabs and new lines are skipped * - an empty command is invalid * * Unix: * - the standard shell quoting and escaping rules are used, see @c g_shell_parse_argv() * - as a consequence, an unqouted # at the start of an argument comments to the end of line * * Windows: * - leading carriage returns are skipped too * - a quoted program name must be entirely inside the quotes. No "C:\Foo\Bar".pdf or * "C:\Foo\Bar".bat, which would be executed by Windows as `C:\Foo\Bar.exe` * - an unquoted program name may not contain spaces. `Foo Bar Qux` will not be considered * `"Foo Bar.exe" Qux` or `"Foo Bar Qux.exe"`, depending on what executables exist, as * Windows normally does. * - the program name must be separated from the arguments by at least one space or tab * - the standard Windows quoting and escaping rules are used: double quote is escaped with * backslash, and any literal backslashes before a double quote must be duplicated. * * If @a execute is TRUE, also checks, using @c g_find_program_in_path(), if the program * specified in @a command_line exists and is executable. * * @param command_line the command line to check. * @param execute whether to check if the command line is really executable. * @param error return location for error. * * @return @c TRUE on success, @c FALSE on error. * * @since 1.25 **/ GEANY_API_SYMBOL gboolean spawn_check_command(const gchar *command_line, gboolean execute, GError **error) { gchar *program = spawn_get_program_name(command_line, error); if (!program) return FALSE; if (execute) { gchar *executable = g_find_program_in_path(program); if (!executable) { g_set_error_literal(error, G_SHELL_ERROR, G_SHELL_ERROR_FAILED, _("Program not found")); g_free(program); return FALSE; } g_free(executable); } g_free(program); return TRUE; } /** * Kills a process. * * @param pid id of the process to kill. * @param error return location for error. * * On Unix, sends a SIGTERM to the process. * * On Windows, terminates the process with exit code 255 (used sometimes as "generic" * error code, or for programs terminated with Ctrl+C / Ctrl+Break). * * @return @c TRUE on success, @c FALSE on error. * * @since 1.25 **/ GEANY_API_SYMBOL gboolean spawn_kill_process(GPid pid, GError **error) { #ifdef G_OS_WIN32 if (!TerminateProcess(pid, 255)) { gchar *message = g_win32_error_message(GetLastError()); g_set_error_literal(error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED, message); g_free(message); return FALSE; } #else if (kill(pid, SIGTERM)) { g_set_error_literal(error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED, g_strerror(errno)); return FALSE; } #endif return TRUE; } #ifdef G_OS_WIN32 static gchar *spawn_create_process_with_pipes(wchar_t *w_command_line, const wchar_t *w_working_directory, void *w_environment, HANDLE *hprocess, int *stdin_fd, int *stdout_fd, int *stderr_fd) { enum { WRITE_STDIN, READ_STDOUT, READ_STDERR, READ_STDIN, WRITE_STDOUT, WRITE_STDERR }; STARTUPINFOW startup; PROCESS_INFORMATION process; HANDLE hpipe[6] = { NULL, NULL, NULL, NULL, NULL, NULL }; int *fd[3] = { stdin_fd, stdout_fd, stderr_fd }; const char *failed; /* failed WIN32/CRTL function, if any */ gchar *message = NULL; /* glib WIN32/CTRL error message */ gchar *failure = NULL; /* full error text */ gboolean pipe_io; int i; ZeroMemory(&startup, sizeof startup); startup.cb = sizeof startup; pipe_io = stdin_fd || stdout_fd || stderr_fd; if (pipe_io) { startup.dwFlags |= STARTF_USESTDHANDLES; /* not all programs accept mixed NULL and non-NULL hStd*, so we create all */ for (i = 0; i < 3; i++) { static int pindex[3][2] = { { READ_STDIN, WRITE_STDIN }, { READ_STDOUT, WRITE_STDOUT }, { READ_STDERR, WRITE_STDERR } }; if (!CreatePipe(&hpipe[pindex[i][0]], &hpipe[pindex[i][1]], NULL, 0)) { hpipe[pindex[i][0]] = hpipe[pindex[i][1]] = NULL; failed = "create pipe"; goto leave; } if (fd[i]) { static int mode[3] = { _O_WRONLY, _O_RDONLY, _O_RDONLY }; if ((*fd[i] = _open_osfhandle((intptr_t) hpipe[i], mode[i])) == -1) { failed = "convert pipe handle to file descriptor"; message = g_strdup(g_strerror(errno)); goto leave; } } else if (!CloseHandle(hpipe[i])) { failed = "close pipe"; goto leave; } if (!SetHandleInformation(hpipe[i + 3], HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT)) { failed = "set pipe handle to inheritable"; goto leave; } } } startup.hStdInput = hpipe[READ_STDIN]; startup.hStdOutput = hpipe[WRITE_STDOUT]; startup.hStdError = hpipe[WRITE_STDERR]; if (!CreateProcessW(NULL, w_command_line, NULL, NULL, TRUE, CREATE_UNICODE_ENVIRONMENT | (pipe_io ? CREATE_NO_WINDOW : 0), w_environment, w_working_directory, &startup, &process)) { failed = ""; /* report the message only */ /* further errors will not be reported */ } else { failed = NULL; CloseHandle(process.hThread); /* we don't need this */ if (hprocess) *hprocess = process.hProcess; else CloseHandle(process.hProcess); } leave: if (failed) { if (!message) { size_t len; message = g_win32_error_message(GetLastError()); len = strlen(message); /* unlike g_strerror(), the g_win32_error messages may include a final '.' */ if (len > 0 && message[len - 1] == '.') message[len - 1] = '\0'; } if (*failed == '\0') failure = message; else { failure = g_strdup_printf("Failed to %s (%s)", failed, message); g_free(message); } } if (pipe_io) { for (i = 0; i < 3; i++) { if (failed) { if (fd[i] && *fd[i] != -1) _close(*fd[i]); else if (hpipe[i]) CloseHandle(hpipe[i]); } if (hpipe[i + 3]) CloseHandle(hpipe[i + 3]); } } return failure; } static void spawn_append_argument(GString *command, const char *text) { const char *s; if (command->len) g_string_append_c(command, ' '); for (s = text; *s; s++) { /* g_ascii_isspace() fails for '\v', and locale spaces (if any) will do no harm */ if (*s == '"' || isspace(*s)) break; } if (*text && !*s) g_string_append(command, text); else { g_string_append_c(command, '"'); for (s = text; *s; s++) { const char *slash; for (slash = s; *slash == '\\'; slash++); if (slash > s) { g_string_append_len(command, s, slash - s); if (!*slash || *slash == '"') { g_string_append_len(command, s, slash - s); if (!*slash) break; } s = slash; } if (*s == '"') g_string_append_c(command, '\\'); g_string_append_c(command, *s); } g_string_append_c(command, '"'); } } #endif /* G_OS_WIN32 */ /* * Executes a child program asynchronously and setups pipes. * * This is the low-level spawning function. Please use @c spawn_with_callbacks() unless * you need to setup specific event source(s). * * A command line or an argument vector must be passed. If both are present, the argument * vector is appended to the command line. An empty command line is not allowed. * * Under Windows, if the child is a console application, and at least one file descriptor is * specified, the new child console (if any) will be hidden. * * If a @a child_pid is passed, it's your responsibility to invoke @c g_spawn_close_pid(). * * @param working_directory child's current working directory, or @c NULL. * @param command_line child program and arguments, or @c NULL. * @param argv child's argument vector, or @c NULL. * @param envp child's environment, or @c NULL. * @param child_pid return location for child process ID, or @c NULL. * @param stdin_fd return location for file descriptor to write to child's stdin, or @c NULL. * @param stdout_fd return location for file descriptor to read child's stdout, or @c NULL. * @param stderr_fd return location for file descriptor to read child's stderr, or @c NULL. * @param error return location for error. * * @return @c TRUE on success, @c FALSE on error. */ static gboolean spawn_async_with_pipes(const gchar *working_directory, const gchar *command_line, gchar **argv, gchar **envp, GPid *child_pid, gint *stdin_fd, gint *stdout_fd, gint *stderr_fd, GError **error) { g_return_val_if_fail(command_line != NULL || argv != NULL, FALSE); #ifdef G_OS_WIN32 GString *command; GArray *w_environment; wchar_t *w_working_directory = NULL; wchar_t *w_command = NULL; gboolean success = TRUE; if (command_line) { gchar *program = spawn_get_program_name(command_line, error); const gchar *arguments; if (!program) return FALSE; command = g_string_new(NULL); arguments = strstr(command_line, program) + strlen(program); if (*arguments == '"') { g_string_append(command, program); arguments++; } else { /* quote the first token, to avoid Windows attemps to run two or more unquoted tokens as a program until an existing file name is found */ g_string_printf(command, "\"%s\"", program); } g_string_append(command, arguments); g_free(program); } else command = g_string_new(NULL); w_environment = g_array_new(TRUE, FALSE, sizeof(wchar_t)); while (argv && *argv) spawn_append_argument(command, *argv++); #if defined(SPAWN_TEST) || defined(GEANY_DEBUG) g_message("full spawn command line: %s", command->str); #endif while (envp && *envp && success) { glong w_entry_len; wchar_t *w_entry; gchar *tmp = NULL; // FIXME: remove this and rely on UTF-8 input if (! g_utf8_validate(*envp, -1, NULL)) { tmp = g_locale_to_utf8(*envp, -1, NULL, NULL, NULL); if (tmp) *envp = tmp; } /* TODO: better error message */ w_entry = g_utf8_to_utf16(*envp, -1, NULL, &w_entry_len, error); if (! w_entry) success = FALSE; else { /* copy the entry, including NUL terminator */ g_array_append_vals(w_environment, w_entry, w_entry_len + 1); g_free(w_entry); } g_free(tmp); envp++; } /* convert working directory into locale encoding */ if (success && working_directory) { GError *gerror = NULL; const gchar *utf8_working_directory; gchar *tmp = NULL; // FIXME: remove this and rely on UTF-8 input if (! g_utf8_validate(working_directory, -1, NULL)) { tmp = g_locale_to_utf8(working_directory, -1, NULL, NULL, NULL); if (tmp) utf8_working_directory = tmp; } else utf8_working_directory = working_directory; w_working_directory = g_utf8_to_utf16(utf8_working_directory, -1, NULL, NULL, &gerror); if (! w_working_directory) { /* TODO use the code below post-1.28 as it introduces a new string g_set_error(error, gerror->domain, gerror->code, _("Failed to convert working directory into locale encoding: %s"), gerror->message); */ g_propagate_error(error, gerror); success = FALSE; } g_free(tmp); } /* convert command into locale encoding */ if (success) { GError *gerror = NULL; const gchar *utf8_cmd; gchar *tmp = NULL; // FIXME: remove this and rely on UTF-8 input if (! g_utf8_validate(command->str, -1, NULL)) { tmp = g_locale_to_utf8(command->str, -1, NULL, NULL, NULL); if (tmp) utf8_cmd = tmp; } else utf8_cmd = command->str; w_command = g_utf8_to_utf16(utf8_cmd, -1, NULL, NULL, &gerror); if (! w_command) { /* TODO use the code below post-1.28 as it introduces a new string g_set_error(error, gerror->domain, gerror->code, _("Failed to convert command into locale encoding: %s"), gerror->message); */ g_propagate_error(error, gerror); success = FALSE; } } if (success) { gchar *failure; failure = spawn_create_process_with_pipes(w_command, w_working_directory, envp ? w_environment->data : NULL, child_pid, stdin_fd, stdout_fd, stderr_fd); if (failure) { g_set_error_literal(error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED, failure); g_free(failure); } success = failure == NULL; } g_string_free(command, TRUE); g_array_free(w_environment, TRUE); g_free(w_working_directory); g_free(w_command); return success; #else /* G_OS_WIN32 */ int cl_argc; char **full_argv; gboolean spawned; GError *gerror = NULL; if (command_line) { int argc = 0; char **cl_argv; if (!spawn_parse_argv(command_line, &cl_argc, &cl_argv, error)) return FALSE; if (argv) for (argc = 0; argv[argc]; argc++); full_argv = g_renew(gchar *, cl_argv, cl_argc + argc + 1); memcpy(full_argv + cl_argc, argv, argc * sizeof(gchar *)); full_argv[cl_argc + argc] = NULL; } else full_argv = argv; spawned = g_spawn_async_with_pipes(working_directory, full_argv, envp, G_SPAWN_SEARCH_PATH | (child_pid ? G_SPAWN_DO_NOT_REAP_CHILD : 0), NULL, NULL, child_pid, stdin_fd, stdout_fd, stderr_fd, &gerror); if (!spawned) { gint en = 0; const gchar *message = gerror->message; /* try to cut glib citing of the program name or working directory: they may be long, and only the caller knows whether they're UTF-8. We lose the exact chdir error. */ switch (gerror->code) { #ifdef EACCES case G_SPAWN_ERROR_ACCES : en = EACCES; break; #endif #ifdef EPERM case G_SPAWN_ERROR_PERM : en = EPERM; break; #endif #ifdef E2BIG case G_SPAWN_ERROR_TOO_BIG : en = E2BIG; break; #endif #ifdef ENOEXEC case G_SPAWN_ERROR_NOEXEC : en = ENOEXEC; break; #endif #ifdef ENAMETOOLONG case G_SPAWN_ERROR_NAMETOOLONG : en = ENAMETOOLONG; break; #endif #ifdef ENOENT case G_SPAWN_ERROR_NOENT : en = ENOENT; break; #endif #ifdef ENOMEM case G_SPAWN_ERROR_NOMEM : en = ENOMEM; break; #endif #ifdef ENOTDIR case G_SPAWN_ERROR_NOTDIR : en = ENOTDIR; break; #endif #ifdef ELOOP case G_SPAWN_ERROR_LOOP : en = ELOOP; break; #endif #ifdef ETXTBUSY case G_SPAWN_ERROR_TXTBUSY : en = ETXTBUSY; break; #endif #ifdef EIO case G_SPAWN_ERROR_IO : en = EIO; break; #endif #ifdef ENFILE case G_SPAWN_ERROR_NFILE : en = ENFILE; break; #endif #ifdef EMFILE case G_SPAWN_ERROR_MFILE : en = EMFILE; break; #endif #ifdef EINVAL case G_SPAWN_ERROR_INVAL : en = EINVAL; break; #endif #ifdef EISDIR case G_SPAWN_ERROR_ISDIR : en = EISDIR; break; #endif #ifdef ELIBBAD case G_SPAWN_ERROR_LIBBAD : en = ELIBBAD; break; #endif case G_SPAWN_ERROR_CHDIR : { message = _("Failed to change to the working directory"); break; } case G_SPAWN_ERROR_FAILED : { message = _("Unknown error executing child process"); break; } } if (en) message = g_strerror(en); g_set_error_literal(error, gerror->domain, gerror->code, message); g_error_free(gerror); } if (full_argv != argv) { full_argv[cl_argc] = NULL; g_strfreev(full_argv); } return spawned; #endif /* G_OS_WIN32 */ } /** * Executes a child asynchronously. * * A command line or an argument vector must be passed. If both are present, the argument * vector is appended to the command line. An empty command line is not allowed. * * If a @a child_pid is passed, it's your responsibility to invoke @c g_spawn_close_pid(). * * @param working_directory @nullable child's current working directory, or @c NULL. * @param command_line @nullable child program and arguments, or @c NULL. * @param argv @nullable child's argument vector, or @c NULL. * @param envp @nullable child's environment, or @c NULL. * @param child_pid @out @optional return location for child process ID, or @c NULL. * @param error return location for error. * * @return @c TRUE on success, @c FALSE on error. * * @since 1.25 **/ GEANY_API_SYMBOL gboolean spawn_async(const gchar *working_directory, const gchar *command_line, gchar **argv, gchar **envp, GPid *child_pid, GError **error) { return spawn_async_with_pipes(working_directory, command_line, argv, envp, child_pid, NULL, NULL, NULL, error); } /* * Spawn with callbacks - general event sequence: * * - Launch the child. * - Setup any I/O callbacks and a child watch callback. * - On sync execution, run a main loop. * - Wait for the child to terminate. * - Check for active I/O sources. If any, add a timeout source to watch them, they should * become inactive real soon now that the child is dead. Otherwise, finalize immediately. * - In the timeout source: check for active I/O sources and finalize if none. */ typedef struct _SpawnChannelData { GIOChannel *channel; /* NULL if not created / already destroyed */ union { GIOFunc write; SpawnReadFunc read; } cb; gpointer cb_data; /* stdout/stderr only */ GString *buffer; /* NULL if recursive */ GString *line_buffer; /* NULL if char buffered */ gsize max_length; /* stdout/stderr: fix continuous empty G_IO_IN-s for recursive channels */ guint empty_gio_ins; } SpawnChannelData; #define SPAWN_CHANNEL_GIO_WATCH(sc) ((sc)->empty_gio_ins < 200) static void spawn_destroy_common(SpawnChannelData *sc) { g_io_channel_shutdown(sc->channel, FALSE, NULL); if (sc->buffer) g_string_free(sc->buffer, TRUE); if (sc->line_buffer) g_string_free(sc->line_buffer, TRUE); } static void spawn_timeout_destroy_cb(gpointer data) { SpawnChannelData *sc = (SpawnChannelData *) data; spawn_destroy_common(sc); g_io_channel_unref(sc->channel); sc->channel = NULL; } static void spawn_destroy_cb(gpointer data) { SpawnChannelData *sc = (SpawnChannelData *) data; if (SPAWN_CHANNEL_GIO_WATCH(sc)) { spawn_destroy_common(sc); sc->channel = NULL; } } static gboolean spawn_write_cb(GIOChannel *channel, GIOCondition condition, gpointer data) { SpawnChannelData *sc = (SpawnChannelData *) data; if (!sc->cb.write(channel, condition, sc->cb_data)) return FALSE; return !(condition & SPAWN_IO_FAILURE); } static gboolean spawn_read_cb(GIOChannel *channel, GIOCondition condition, gpointer data); static gboolean spawn_timeout_read_cb(gpointer data) { SpawnChannelData *sc = (SpawnChannelData *) data; /* The solution for continuous empty G_IO_IN-s is to generate them outselves. :) */ return spawn_read_cb(sc->channel, G_IO_IN, data); } static gboolean spawn_read_cb(GIOChannel *channel, GIOCondition condition, gpointer data) { SpawnChannelData *sc = (SpawnChannelData *) data; GString *line_buffer = sc->line_buffer; GString *buffer = sc->buffer ? sc->buffer : g_string_sized_new(sc->max_length); GIOCondition input_cond = condition & (G_IO_IN | G_IO_PRI); GIOCondition failure_cond = condition & SPAWN_IO_FAILURE; GIOStatus status = G_IO_STATUS_NORMAL; /* * - Normally, read only once. With IO watches, our data processing must be immediate, * which may give the child time to emit more data, and a read loop may combine it into * large stdout and stderr portions. Under Windows, looping blocks. * - On failure, read in a loop. It won't block now, there will be no more data, and the * IO watch is not guaranteed to be called again (under Windows this is the last call). * - When using timeout callbacks, read in a loop. Otherwise, the input processing will * be limited to (1/0.050 * DEFAULT_IO_LENGTH) KB/sec, which is pretty low. */ if (input_cond) { gsize chars_read; if (line_buffer) { gsize n = line_buffer->len; while ((status = g_io_channel_read_chars(channel, line_buffer->str + n, DEFAULT_IO_LENGTH, &chars_read, NULL)) == G_IO_STATUS_NORMAL) { g_string_set_size(line_buffer, n + chars_read); while (n < line_buffer->len) { gsize line_len = 0; if (n == sc->max_length) line_len = n; else if (strchr("\n", line_buffer->str[n])) /* '\n' or '\0' */ line_len = n + 1; else if (n < line_buffer->len - 1 && line_buffer->str[n] == '\r') line_len = n + 1 + (line_buffer->str[n + 1] == '\n'); if (!line_len) n++; else { g_string_append_len(buffer, line_buffer->str, line_len); g_string_erase(line_buffer, 0, line_len); /* input only, failures are reported separately below */ sc->cb.read(buffer, input_cond, sc->cb_data); g_string_truncate(buffer, 0); n = 0; } } if (SPAWN_CHANNEL_GIO_WATCH(sc) && !failure_cond) break; } } else { while ((status = g_io_channel_read_chars(channel, buffer->str, sc->max_length, &chars_read, NULL)) == G_IO_STATUS_NORMAL) { g_string_set_size(buffer, chars_read); /* input only, failures are reported separately below */ sc->cb.read(buffer, input_cond, sc->cb_data); if (SPAWN_CHANNEL_GIO_WATCH(sc) && !failure_cond) break; } } /* Under OSX, after child death, the read watches receive input conditions instead of error conditions, so we convert the termination statuses into conditions. Should not hurt the other OS. */ if (status == G_IO_STATUS_ERROR) failure_cond |= G_IO_ERR; else if (status == G_IO_STATUS_EOF) failure_cond |= G_IO_HUP; } if (failure_cond) /* we must signal the callback */ { if (line_buffer && line_buffer->len) /* flush the line buffer */ { g_string_append_len(buffer, line_buffer->str, line_buffer->len); /* all data may be from a previous call */ if (!input_cond) input_cond = G_IO_IN; } else { input_cond = 0; g_string_truncate(buffer, 0); } sc->cb.read(buffer, input_cond | failure_cond, sc->cb_data); } /* Check for continuous activations with G_IO_IN | G_IO_PRI, without any data to read and without errors. If detected, switch to timeout source. */ else if (SPAWN_CHANNEL_GIO_WATCH(sc) && status == G_IO_STATUS_AGAIN) { sc->empty_gio_ins++; if (!SPAWN_CHANNEL_GIO_WATCH(sc)) { GSource *old_source = g_main_current_source(); GSource *new_source = g_timeout_source_new(50); geany_debug("Switching spawn source %s ((GSource*)%p on (GIOChannel*)%p) to a timeout source", g_source_get_name(old_source), (gpointer) old_source, (gpointer)sc->channel); g_io_channel_ref(sc->channel); g_source_set_can_recurse(new_source, g_source_get_can_recurse(old_source)); g_source_set_callback(new_source, spawn_timeout_read_cb, data, spawn_timeout_destroy_cb); g_source_attach(new_source, g_source_get_context(old_source)); g_source_unref(new_source); failure_cond |= G_IO_ERR; } } if (buffer != sc->buffer) g_string_free(buffer, TRUE); return !failure_cond; } typedef struct _SpawnWatcherData { SpawnChannelData sc[3]; /* stdin, stdout, stderr */ GChildWatchFunc exit_cb; gpointer exit_data; GPid pid; gint exit_status; GMainContext *main_context; /* NULL if async execution */ GMainLoop *main_loop; /* NULL if async execution */ } SpawnWatcherData; static void spawn_finalize(SpawnWatcherData *sw) { if (sw->exit_cb) sw->exit_cb(sw->pid, sw->exit_status, sw->exit_data); if (sw->main_loop) { g_main_loop_quit(sw->main_loop); g_main_loop_unref(sw->main_loop); } g_spawn_close_pid(sw->pid); g_slice_free(SpawnWatcherData, sw); } static gboolean spawn_timeout_watch_cb(gpointer data) { SpawnWatcherData *sw = (SpawnWatcherData *) data; int i; for (i = 0; i < 3; i++) if (sw->sc[i].channel) return TRUE; spawn_finalize(sw); return FALSE; } static void spawn_watch_cb(GPid pid, gint status, gpointer data) { SpawnWatcherData *sw = (SpawnWatcherData *) data; int i; sw->pid = pid; sw->exit_status = status; for (i = 0; i < 3; i++) { if (sw->sc[i].channel) { GSource *source = g_timeout_source_new(50); g_source_set_callback(source, spawn_timeout_watch_cb, data, NULL); g_source_attach(source, sw->main_context); g_source_unref(source); return; } } spawn_finalize(sw); } /** @girskip * Executes a child program and setups callbacks. * * A command line or an argument vector must be passed. If both are present, the argument * vector is appended to the command line. An empty command line is not allowed. * * The synchronous execution may not be combined with recursive callbacks. * * In line buffered mode, the child input is broken on `\n`, `\r\n`, `\r`, `\0` and max length. * * All I/O callbacks are guaranteed to be invoked at least once with @c G_IO_ERR, @c G_IO_HUP * or @c G_IO_NVAL set (except for a @a stdin_cb which returns @c FALSE before that). For the * non-recursive callbacks, this is guaranteed to be the last call, and may be used to free any * resources associated with the callback. * * The @a stdin_cb may write to @c channel only once per invocation, only if @c G_IO_OUT is * set, and only a non-zero number of characters. * * @c stdout_cb and @c stderr_cb may modify the received strings in any way, but must not * free them. * * The default max lengths are 24K for line buffered stdout, 8K for line buffered stderr, * 4K for unbuffered input under Unix, and 2K for unbuffered input under Windows. * * Due to a bug in some glib versions, the sources for recursive stdout/stderr callbacks may * be converted from child watch to timeout(50ms). No callback changes are required. * * @c exit_cb is always invoked last, after all I/O callbacks. * * The @a child_pid will be closed automatically, after @a exit_cb is invoked. * * @param working_directory @nullable child's current working directory, or @c NULL. * @param command_line @nullable child program and arguments, or @c NULL. * @param argv @nullable child's argument vector, or @c NULL. * @param envp @nullable child's environment, or @c NULL. * @param spawn_flags flags from SpawnFlags. * @param stdin_cb @nullable callback to send data to childs's stdin, or @c NULL. * @param stdin_data data to pass to @a stdin_cb. * @param stdout_cb @nullable callback to receive child's stdout, or @c NULL. * @param stdout_data data to pass to @a stdout_cb. * @param stdout_max_length maximum data length to pass to stdout_cb, @c 0 = default. * @param stderr_cb @nullable callback to receive child's stderr, or @c NULL. * @param stderr_data data to pass to @a stderr_cb. * @param stderr_max_length maximum data length to pass to stderr_cb, @c 0 = default. * @param exit_cb @nullable callback to invoke when the child exits, or @c NULL. * @param exit_data data to pass to @a exit_cb. * @param child_pid @out @optional return location for child process ID, or @c NULL. * @param error return location for error. * * @return @c TRUE on success, @c FALSE on error. * * @since 1.25 **/ GEANY_API_SYMBOL gboolean spawn_with_callbacks(const gchar *working_directory, const gchar *command_line, gchar **argv, gchar **envp, SpawnFlags spawn_flags, GIOFunc stdin_cb, gpointer stdin_data, SpawnReadFunc stdout_cb, gpointer stdout_data, gsize stdout_max_length, SpawnReadFunc stderr_cb, gpointer stderr_data, gsize stderr_max_length, GChildWatchFunc exit_cb, gpointer exit_data, GPid *child_pid, GError **error) { GPid pid; int pipe[3] = { -1, -1, -1 }; g_return_val_if_fail(!(spawn_flags & SPAWN_RECURSIVE) || !(spawn_flags & SPAWN_SYNC), FALSE); if (spawn_async_with_pipes(working_directory, command_line, argv, envp, &pid, stdin_cb ? &pipe[0] : NULL, stdout_cb ? &pipe[1] : NULL, stderr_cb ? &pipe[2] : NULL, error)) { SpawnWatcherData *sw = g_slice_new0(SpawnWatcherData); gpointer cb_data[3] = { stdin_data, stdout_data, stderr_data }; GSource *source; int i; sw->main_context = spawn_flags & SPAWN_SYNC ? g_main_context_new() : NULL; if (child_pid) *child_pid = pid; for (i = 0; i < 3; i++) { SpawnChannelData *sc = &sw->sc[i]; GIOCondition condition; GSourceFunc callback; if (pipe[i] == -1) continue; #ifdef G_OS_WIN32 sc->channel = g_io_channel_win32_new_fd(pipe[i]); #else sc->channel = g_io_channel_unix_new(pipe[i]); g_io_channel_set_flags(sc->channel, G_IO_FLAG_NONBLOCK, NULL); #endif g_io_channel_set_encoding(sc->channel, NULL, NULL); /* we have our own buffers, and GIO buffering blocks under Windows */ g_io_channel_set_buffered(sc->channel, FALSE); sc->cb_data = cb_data[i]; if (i == 0) { sc->cb.write = stdin_cb; condition = G_IO_OUT | SPAWN_IO_FAILURE; callback = (GSourceFunc) spawn_write_cb; } else { gboolean line_buffered = !(spawn_flags & ((SPAWN_STDOUT_UNBUFFERED >> 1) << i)); condition = G_IO_IN | G_IO_PRI | SPAWN_IO_FAILURE; callback = (GSourceFunc) spawn_read_cb; if (i == 1) { sc->cb.read = stdout_cb; sc->max_length = stdout_max_length ? stdout_max_length : line_buffered ? 24576 : DEFAULT_IO_LENGTH; } else { sc->cb.read = stderr_cb; sc->max_length = stderr_max_length ? stderr_max_length : line_buffered ? 8192 : DEFAULT_IO_LENGTH; } if (line_buffered) { sc->line_buffer = g_string_sized_new(sc->max_length + DEFAULT_IO_LENGTH); } sc->empty_gio_ins = 0; } source = g_io_create_watch(sc->channel, condition); g_io_channel_unref(sc->channel); if (spawn_flags & (SPAWN_STDIN_RECURSIVE << i)) g_source_set_can_recurse(source, TRUE); else if (i) /* to avoid new string on each call */ sc->buffer = g_string_sized_new(sc->max_length); g_source_set_callback(source, callback, sc, spawn_destroy_cb); g_source_attach(source, sw->main_context); g_source_unref(source); } sw->exit_cb = exit_cb; sw->exit_data = exit_data; source = g_child_watch_source_new(pid); g_source_set_callback(source, (GSourceFunc) spawn_watch_cb, sw, NULL); g_source_attach(source, sw->main_context); g_source_unref(source); if (spawn_flags & SPAWN_SYNC) { sw->main_loop = g_main_loop_new(sw->main_context, FALSE); g_main_context_unref(sw->main_context); g_main_loop_run(sw->main_loop); } return TRUE; } return FALSE; } /** * Writes (a portion of) the data pointed by @a data->ptr to the @a channel. * * If @c G_IO_OUT in @a condition is set, and the @a data->size is > 0, attempts to write * @a data->ptr (or a portion of it, depending on the size) to the @a channel. On success, * increases ptr and decreases size with the number of characters written. * * This function may converted to @c GIOFunc and passed to @c spawn_with_callbacks() as * @c stdin_cb, together with a @c SpawnWriteData for @c stdin_data. As with any other * callback data, make sure that @c stdin_data exists while the child is being executed. * (For example, on asynchronous execution, you can allocate the data in the heap, and free * it in your @c spawn_with_callbacks() @c exit_cb callback.) * * @param channel the channel to write data to. * @param condition condition to check for @c G_IO_OUT. * @param data @c SpawnWriteData to write to @a channel. * * @return @c TRUE if the remaining size is > 0 and @a condition does not indicate any error, * @c FALSE otherwise. * * @since 1.25 **/ GEANY_API_SYMBOL gboolean spawn_write_data(GIOChannel *channel, GIOCondition condition, SpawnWriteData *data) { if ((condition & G_IO_OUT) && data->size) { gsize chars_written = 0; g_io_channel_write_chars(channel, data->ptr, data->size < DEFAULT_IO_LENGTH ? data->size : DEFAULT_IO_LENGTH, &chars_written, NULL); /* "This can be nonzero even if the return value is not G_IO_STATUS_NORMAL." */ if (chars_written) { data->ptr += chars_written; data->size -= chars_written; } } return data->size > 0 && !(condition & SPAWN_IO_FAILURE); } static void spawn_append_gstring_cb(GString *string, GIOCondition condition, gpointer data) { if (condition & (G_IO_IN | G_IO_PRI)) g_string_append_len((GString *) data, string->str, string->len); } static void spawn_get_exit_status_cb(G_GNUC_UNUSED GPid pid, gint status, gpointer exit_status) { *(gint *) exit_status = status; } /** * Executes a child synchronously. * * A command line or an argument vector must be passed. If both are present, the argument * vector is appended to the command line. An empty command line is not allowed. * * The @a stdin_data is sent to the child with @c spawn_write_data(). * * All output from the child, including the nul characters, is stored in @a stdout_data and * @a stderr_data (if non-NULL). Any existing data in these strings will be erased. * * @param working_directory @nullable child's current working directory, or @c NULL. * @param command_line @nullable child program and arguments, or @c NULL. * @param argv @nullable child's argument vector, or @c NULL. * @param envp @nullable child's environment, or @c NULL. * @param stdin_data @nullable data to send to childs's stdin, or @c NULL. * @param stdout_data @nullable GString location to receive the child's stdout, or @c NULL. * @param stderr_data @nullable GString location to receive the child's stderr, or @c NULL. * @param exit_status @out @optional return location for the child exit code, or @c NULL. * @param error return location for error. * * @return @c TRUE on success, @c FALSE on error. * * @since 1.25 **/ GEANY_API_SYMBOL gboolean spawn_sync(const gchar *working_directory, const gchar *command_line, gchar **argv, gchar **envp, SpawnWriteData *stdin_data, GString *stdout_data, GString *stderr_data, gint *exit_status, GError **error) { if (stdout_data) g_string_truncate(stdout_data, 0); if (stderr_data) g_string_truncate(stderr_data, 0); return spawn_with_callbacks(working_directory, command_line, argv, envp, SPAWN_SYNC | SPAWN_UNBUFFERED, stdin_data ? (GIOFunc) spawn_write_data : NULL, stdin_data, stdout_data ? spawn_append_gstring_cb : NULL, stdout_data, 0, stderr_data ? spawn_append_gstring_cb : NULL, stderr_data, 0, exit_status ? spawn_get_exit_status_cb : NULL, exit_status, NULL, error); } /* tests, not part of the API */ #ifdef SPAWN_TEST #include static gboolean read_line(const char *prompt, char *buffer, size_t size) { fputs(prompt, stderr); *buffer = '\0'; if (fgets(buffer, size, stdin)) { char *s = strchr(buffer, '\n'); if (s) *s = '\0'; } return *buffer; } static GString *read_string(const char *prompt) { char buffer[0x1000]; /* larger portions for spawn < file */ GString *string = g_string_sized_new(sizeof buffer); while (read_line(prompt, buffer, sizeof buffer)) { if (string->len) g_string_append_c(string, '\n'); g_string_append(string, buffer); } if (!string->len) { g_string_free(string, TRUE); string = NULL; } return string; } static void print_cb(GString *string, GIOCondition condition, gpointer data) { if (condition & (G_IO_IN | G_IO_PRI)) { gsize i; printf("%s: ", (const gchar *) data); /*fputs(string->str, stdout);*/ for (i = 0; i < string->len; i++) { unsigned char c = (unsigned char) string->str[i]; printf(c >= ' ' && c < 0x80 ? "%c" : "\\x%02x", c); } putchar('\n'); } } static void print_status(gint status) { fputs("finished, ", stderr); if (SPAWN_WIFEXITED(status)) fprintf(stderr, "exit code %d\n", SPAWN_WEXITSTATUS(status)); else fputs("abnormal termination\n", stderr); } static void exit_cb(GPid pid, gint status, G_GNUC_UNUSED gpointer data) { fprintf(stderr, "process %u ", (guint) pid); print_status(status); } static void watch_cb(GPid pid, gint status, gpointer data) { g_spawn_close_pid(pid); exit_cb(pid, status, NULL); g_main_loop_quit((GMainLoop *) data); } int main(int argc, char **argv) { char *test_type; if (argc != 2) { fputs("usage: spawn \n", stderr); return 1; } test_type = argv[1]; if (!strcmp(test_type, "syntax") || !strcmp(test_type, "syntexec")) { char command_line[0x100]; while (read_line("command line: ", command_line, sizeof command_line)) { GError *error = NULL; if (spawn_check_command(command_line, argv[1][4] == 'e', &error)) fputs("valid\n", stderr); else { fprintf(stderr, "error: %s\n", error->message); g_error_free(error); } } } else if (!strcmp(test_type, "execute")) { char command_line[0x100]; while (read_line("command line: ", command_line, sizeof command_line)) { char working_directory[0x100]; char args[4][0x100]; char envs[4][0x100]; char *argv[] = { args[0], args[1], args[2], args[3], NULL }; char *envp[] = { envs[0], envs[1], envs[2], envs[3], NULL }; int i; GPid pid; GError *error = NULL; read_line("working directory: ", working_directory, sizeof working_directory); fputs("up to 4 arguments\n", stderr); for (i = 0; i < 4 && read_line("argument: ", args[i], sizeof args[i]); i++); argv[i] = NULL; fputs("up to 4 variables, or empty line for parent environment\n", stderr); for (i = 0; i < 4 && read_line("variable: ", envs[i], sizeof envs[i]); i++); envp[i] = NULL; if (spawn_async_with_pipes(*working_directory ? working_directory : NULL, *command_line ? command_line : NULL, argv, i ? envp : NULL, &pid, NULL, NULL, NULL, &error)) { GMainLoop *loop = g_main_loop_new(NULL, TRUE); g_child_watch_add(pid, watch_cb, loop); g_main_loop_run(loop); g_main_loop_unref(loop); } else { fprintf(stderr, "error: %s\n", error->message); g_error_free(error); } } } else if (!strcmp(test_type, "redirect") || !strcmp(test_type, "redinput")) { char command_line[0x100]; gboolean output = test_type[4] == 'r'; while (read_line("command line: ", command_line, sizeof command_line)) { GString *stdin_text = read_string("text to send: "); SpawnWriteData stdin_data; GError *error = NULL; if (stdin_text) { stdin_data.ptr = stdin_text->str; stdin_data.size = stdin_text->len; } if (!spawn_with_callbacks(NULL, command_line, NULL, NULL, SPAWN_SYNC, stdin_text ? (GIOFunc) spawn_write_data : NULL, &stdin_data, output ? print_cb : NULL, "stdout", 0, output ? print_cb : NULL, "stderr", 0, exit_cb, NULL, NULL, &error)) { fprintf(stderr, "error: %s\n", error->message); g_error_free(error); } if (stdin_text) g_string_free(stdin_text, TRUE); } } else if (!strcmp(test_type, "capture")) { char command_line[0x100]; while (read_line("command line: ", command_line, sizeof command_line)) { GString *stdin_text = read_string("text to send: "); SpawnWriteData stdin_data = { NULL, 0 }; GString *stdout_data = g_string_sized_new(0x10000); /* may grow */ GString *stderr_data = g_string_sized_new(0x1000); /* may grow */ gint exit_status; GError *error = NULL; if (stdin_text) { stdin_data.ptr = stdin_text->str; stdin_data.size = stdin_text->len; } if (spawn_sync(NULL, command_line, NULL, NULL, &stdin_data, stdout_data, stderr_data, &exit_status, &error)) { printf("stdout: %s\n", stdout_data->str); printf("stderr: %s\n", stderr_data->str); print_status(exit_status); } else { fprintf(stderr, "error: %s\n", error->message); g_error_free(error); } if (stdin_text) g_string_free(stdin_text, TRUE); g_string_free(stdout_data, TRUE); g_string_free(stderr_data, TRUE); } } else { fprintf(stderr, "spawn: unknown test type '%s'", argv[1]); return 1; } return 0; } #endif /* SPAWN_TEST */ geany-2.0/src/keybindingsprivate.h0000644000175000017500000000343514514252267014255 00000000000000/* * keybindingsprivate.h - this file is part of Geany, a fast and lightweight IDE * * Copyright 2014 The Geany contributors * * This program 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; either version 2 of the License, or * (at your option) any later version. * * This program 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef GEANY_KEYBINDINGS_PRIVATE_H #define GEANY_KEYBINDINGS_PRIVATE_H 1 #include "keybindings.h" #include G_BEGIN_DECLS struct GeanyKeyGroup { const gchar *name; /* Group name used in the configuration file, such as @c "html_chars" */ const gchar *label; /* Group label used in the preferences dialog keybindings tab */ GeanyKeyGroupCallback callback; /* use this or individual keybinding callbacks */ gboolean plugin; /* used by plugin */ GPtrArray *key_items; /* pointers to GeanyKeyBinding structs */ gsize plugin_key_count; /* number of keybindings the group holds */ GeanyKeyBinding *plugin_keys; /* array of GeanyKeyBinding structs */ GeanyKeyGroupFunc cb_func; /* use this or individual keybinding callbacks (new style) */ gpointer cb_data; GDestroyNotify cb_data_destroy; /* used to destroy handler_data */ }; G_END_DECLS #endif /* GEANY_KEYBINDINGS_PRIVATE_H */ geany-2.0/src/documentprivate.h0000644000175000017500000000760414514252267013567 00000000000000/* * document-private.h - this file is part of Geany, a fast and lightweight IDE * * Copyright 2008 The Geany contributors * * This program 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; either version 2 of the License, or * (at your option) any later version. * * This program 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef GEANY_DOCUMENT_PRIVATE_H #define GEANY_DOCUMENT_PRIVATE_H 1 #include G_BEGIN_DECLS /* available UNDO actions, UNDO_SCINTILLA is a pseudo action to trigger Scintilla's * undo management */ enum { UNDO_SCINTILLA = 0, UNDO_ENCODING, UNDO_BOM, UNDO_RELOAD, UNDO_EOL, UNDO_ACTIONS_MAX }; typedef struct UndoReloadData { guint actions_count; /* How many following undo/redo actions need to be applied. */ gint eol_mode; /* End-Of-Line mode before/after reloading. */ } UndoReloadData; typedef enum { FILE_OK, FILE_CHANGED, /* also valid for deleted files */ FILE_IGNORE } FileDiskStatus; typedef struct FileEncoding { gchar *encoding; gboolean has_bom; } FileEncoding; enum { MSG_TYPE_RELOAD, MSG_TYPE_RESAVE, MSG_TYPE_POST_RELOAD, NUM_MSG_TYPES }; /* Private GeanyDocument fields */ typedef struct GeanyDocumentPrivate { /* GtkLabel shown in the notebook header. */ GtkWidget *tab_label; /* GtkTreeView object for this document within the Symbols treeview of the sidebar. */ GtkWidget *tag_tree; /* GtkTreeStore object for this document within the Symbols treeview of the sidebar. */ GtkTreeStore *tag_store; /* Indicates whether tag tree has to be updated */ gboolean tag_tree_dirty; /* Iter for this document within the Open Files treeview of the sidebar. */ GtkTreeIter iter; /* Used by the Undo/Redo management code. */ GTrashStack *undo_actions; /* Used by the Undo/Redo management code. */ GTrashStack *redo_actions; /* Used so Undo/Redo works for encoding changes. */ FileEncoding saved_encoding; gboolean colourise_needed; /* use document.c:queue_colourise() instead */ guint keyword_hash; /* hash of keyword string used for typename colourisation */ gint line_count; /* Number of lines in the document. */ gint symbol_list_sort_mode; /* indicates whether a file is on a remote filesystem, works only with GIO/GVfs */ gboolean is_remote; /* File status on disk of the document */ FileDiskStatus file_disk_status; /* Reference to a GFileMonitor object, only used when GIO file monitoring is used. */ gpointer monitor; /* Time of the last disk check, only used when legacy file monitoring is used. */ time_t last_check; /* Modification time of the document on disk, only used when legacy file monitoring is used. */ time_t mtime; /* ID of the idle callback updating the tag list */ guint tag_list_update_source; /* Whether it's temporarily protected (read-only and saving needs confirmation). Does * not imply doc->readonly as writable files can be protected */ gint protected; /* Save pointer to info bars allowing to cancel them programatically (to avoid multiple ones) */ GtkWidget *info_bars[NUM_MSG_TYPES]; /* Keyed Data List to attach arbitrary data to the document */ GData *data; /* Text used for filtering symbol tree. */ gchar *tag_filter; /* Group symbols in symbol tree by their type. */ gboolean symbols_group_by_type; } GeanyDocumentPrivate; G_END_DECLS #endif /* GEANY_DOCUMENT_PRIVATE_H */ geany-2.0/src/pluginutils.h0000644000175000017500000000537014514252267012733 00000000000000/* * pluginutils.h - this file is part of Geany, a fast and lightweight IDE * * Copyright 2009 The Geany contributors * * This program 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; either version 2 of the License, or * (at your option) any later version. * * This program 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef GEANY_PLUGIN_UTILS_H #define GEANY_PLUGIN_UTILS_H 1 #ifdef HAVE_PLUGINS #include "keybindings.h" /* GeanyKeyGroupCallback */ #include "gtkcompat.h" G_BEGIN_DECLS /* avoid including plugindata.h otherwise this redefines the GEANY() macro */ struct GeanyPlugin; struct GeanyDocument; gint geany_api_version(void); void plugin_add_toolbar_item(struct GeanyPlugin *plugin, GtkToolItem *item); void plugin_module_make_resident(struct GeanyPlugin *plugin); void plugin_signal_connect(struct GeanyPlugin *plugin, GObject *object, const gchar *signal_name, gboolean after, GCallback callback, gpointer user_data); guint plugin_timeout_add(struct GeanyPlugin *plugin, guint interval, GSourceFunc function, gpointer data); guint plugin_timeout_add_seconds(struct GeanyPlugin *plugin, guint interval, GSourceFunc function, gpointer data); guint plugin_idle_add(struct GeanyPlugin *plugin, GSourceFunc function, gpointer data); struct GeanyKeyGroup *plugin_set_key_group(struct GeanyPlugin *plugin, const gchar *section_name, gsize count, GeanyKeyGroupCallback callback); GeanyKeyGroup *plugin_set_key_group_full(struct GeanyPlugin *plugin, const gchar *section_name, gsize count, GeanyKeyGroupFunc cb, gpointer pdata, GDestroyNotify destroy_notify); void plugin_show_configure(struct GeanyPlugin *plugin); void plugin_builder_connect_signals(struct GeanyPlugin *plugin, GtkBuilder *builder, gpointer user_data); gpointer plugin_get_document_data(struct GeanyPlugin *plugin, struct GeanyDocument *doc, const gchar *key); void plugin_set_document_data(struct GeanyPlugin *plugin, struct GeanyDocument *doc, const gchar *key, gpointer data); void plugin_set_document_data_full(struct GeanyPlugin *plugin, struct GeanyDocument *doc, const gchar *key, gpointer data, GDestroyNotify free_func); G_END_DECLS #endif /* HAVE_PLUGINS */ #endif /* GEANY_PLUGIN_UTILS_H */ geany-2.0/src/symbols.h0000644000175000017500000000365714514252267012052 00000000000000/* * symbols.h - this file is part of Geany, a fast and lightweight IDE * * Copyright 2006 The Geany contributors * * This program 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; either version 2 of the License, or * (at your option) any later version. * * This program 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef GEANY_SYMBOLS_H #define GEANY_SYMBOLS_H 1 #include "document.h" #include G_BEGIN_DECLS const gchar *symbols_get_context_separator(gint ft_id); #ifdef GEANY_PRIVATE enum { SYMBOLS_SORT_BY_NAME, SYMBOLS_SORT_BY_APPEARANCE, SYMBOLS_SORT_USE_PREVIOUS }; void symbols_init(void); void symbols_finalize(void); void symbols_reload_config_files(void); void symbols_global_tags_loaded(guint file_type_idx); GString *symbols_find_typenames_as_string(TMParserType lang, gboolean global); gboolean symbols_recreate_tag_list(GeanyDocument *doc, gint sort_mode); gint symbols_generate_global_tags(gint argc, gchar **argv, gboolean want_preprocess); void symbols_show_load_tags_dialog(void); gboolean symbols_goto_tag(const gchar *name, gboolean definition); gint symbols_get_current_function(GeanyDocument *doc, const gchar **tagname); gint symbols_get_current_scope(GeanyDocument *doc, const gchar **tagname); const gchar *symbols_get_icon_name(guint icon_id); #endif /* GEANY_PRIVATE */ G_END_DECLS #endif /* GEANY_SYMBOLS_H */ geany-2.0/src/navqueue.h0000644000175000017500000000262314514252267012203 00000000000000/* * navqueue.h - this file is part of Geany, a fast and lightweight IDE * * Copyright 2007 The Geany contributors * * This program 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; either version 2 of the License, or * (at your option) any later version. * * This program 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /** * @file navqueue.h * Simple code navigation **/ #ifndef GEANY_NAVQUEUE_H #define GEANY_NAVQUEUE_H 1 #include "document.h" #include G_BEGIN_DECLS gboolean navqueue_goto_line(GeanyDocument *old_doc, GeanyDocument *new_doc, gint line); #ifdef GEANY_PRIVATE void navqueue_init(void); void navqueue_free(void); void navqueue_remove_file(const gchar *filename); void navqueue_go_back(void); void navqueue_go_forward(void); #endif /* GEANY_PRIVATE */ G_END_DECLS #endif /* GEANY_NAVQUEUE_H */ geany-2.0/src/plugins.c0000644000175000017500000016700714514252267012036 00000000000000/* * plugins.c - this file is part of Geany, a fast and lightweight IDE * * Copyright 2007 The Geany contributors * * This program 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; either version 2 of the License, or * (at your option) any later version. * * This program 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /* Code to manage, load and unload plugins. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #ifdef HAVE_PLUGINS #include "plugins.h" #include "app.h" #include "dialogs.h" #include "documentprivate.h" #include "encodings.h" #include "geanyobject.h" #include "geanywraplabel.h" #include "highlighting.h" #include "keybindingsprivate.h" #include "keyfile.h" #include "main.h" #include "msgwindow.h" #include "navqueue.h" #include "plugindata.h" #include "pluginprivate.h" #include "pluginutils.h" #include "prefs.h" #include "sciwrappers.h" #include "stash.h" #include "support.h" #include "symbols.h" #include "templates.h" #include "toolbar.h" #include "ui_utils.h" #include "utils.h" #include "win32.h" #include #include typedef struct { gchar *prefix; GeanyDocument *document; } ForEachDocData; GList *active_plugin_list = NULL; /* list of only actually loaded plugins, always valid */ static gboolean want_plugins = FALSE; /* list of all available, loadable plugins, only valid as long as the plugin manager dialog is * opened, afterwards it will be destroyed */ static GList *plugin_list = NULL; static gchar **active_plugins_pref = NULL; /* list of plugin filenames to load at startup */ static GList *failed_plugins_list = NULL; /* plugins the user wants active but can't be used */ static GtkWidget *menu_separator = NULL; static gchar *get_plugin_path(void); static void pm_show_dialog(GtkMenuItem *menuitem, gpointer user_data); typedef struct { gchar extension[8]; Plugin *plugin; /* &builtin_so_proxy_plugin for native plugins */ } PluginProxy; static gpointer plugin_load_gmodule(GeanyPlugin *proxy, GeanyPlugin *plugin, const gchar *filename, gpointer pdata); static void plugin_unload_gmodule(GeanyPlugin *proxy, GeanyPlugin *plugin, gpointer load_data, gpointer pdata); static Plugin builtin_so_proxy_plugin = { .proxy_cbs = { .load = plugin_load_gmodule, .unload = plugin_unload_gmodule, }, /* rest of Plugin can be NULL/0 */ }; static PluginProxy builtin_so_proxy = { .extension = G_MODULE_SUFFIX, .plugin = &builtin_so_proxy_plugin, }; static GQueue active_proxies = G_QUEUE_INIT; static void plugin_free(Plugin *plugin); static GeanyData geany_data; static void geany_data_init(void) { GeanyData gd = { app, &main_widgets, documents_array, filetypes_array, &prefs, &interface_prefs, &toolbar_prefs, &editor_prefs, &file_prefs, &search_prefs, &tool_prefs, &template_prefs, NULL, /* Remove field on next ABI break (abi-todo) */ filetypes_by_title, geany_object, }; geany_data = gd; } /* In order to have nested proxies work the count of dependent plugins must propagate up. * This prevents that any plugin in the tree is unloaded while a leaf plugin is active. */ static void proxied_count_inc(Plugin *proxy) { do { proxy->proxied_count += 1; proxy = proxy->proxy; } while (proxy != NULL); } static void proxied_count_dec(Plugin *proxy) { g_warn_if_fail(proxy->proxied_count > 0); do { proxy->proxied_count -= 1; proxy = proxy->proxy; } while (proxy != NULL); } /* Prevent the same plugin filename being loaded more than once. * Note: g_module_name always returns the .so name, even when Plugin::filename is a .la file. */ static gboolean plugin_loaded(Plugin *plugin) { gchar *basename_module, *basename_loaded; GList *item; basename_module = g_path_get_basename(plugin->filename); for (item = plugin_list; item != NULL; item = g_list_next(item)) { basename_loaded = g_path_get_basename(((Plugin*)item->data)->filename); if (utils_str_equal(basename_module, basename_loaded)) { g_free(basename_loaded); g_free(basename_module); return TRUE; } g_free(basename_loaded); } /* Look also through the list of active plugins. This prevents problems when we have the same * plugin in libdir/geany/ AND in configdir/plugins/ and the one in libdir/geany/ is loaded * as active plugin. The plugin manager list would only take the one in configdir/geany/ and * the plugin manager would list both plugins. Additionally, unloading the active plugin * would cause a crash. */ for (item = active_plugin_list; item != NULL; item = g_list_next(item)) { basename_loaded = g_path_get_basename(((Plugin*)item->data)->filename); if (utils_str_equal(basename_module, basename_loaded)) { g_free(basename_loaded); g_free(basename_module); return TRUE; } g_free(basename_loaded); } g_free(basename_module); return FALSE; } static Plugin *find_active_plugin_by_name(const gchar *filename) { GList *item; g_return_val_if_fail(filename, FALSE); for (item = active_plugin_list; item != NULL; item = g_list_next(item)) { if (utils_str_equal(filename, ((Plugin*)item->data)->filename)) return item->data; } return NULL; } /* Mimics plugin_version_check() of legacy plugins for use with plugin_check_version() below */ #define PLUGIN_VERSION_CODE(api, abi) ((abi) != GEANY_ABI_VERSION ? -1 : (api)) static gboolean plugin_check_version(Plugin *plugin, int plugin_version_code) { gboolean ret = TRUE; if (plugin_version_code < 0) { gchar *name = g_path_get_basename(plugin->filename); msgwin_status_add(_("The plugin \"%s\" is not binary compatible with this " "release of Geany - please recompile it."), name); geany_debug("Plugin \"%s\" is not binary compatible with this " "release of Geany - recompile it.", name); ret = FALSE; g_free(name); } else if (plugin_version_code > GEANY_API_VERSION) { gchar *name = g_path_get_basename(plugin->filename); geany_debug("Plugin \"%s\" requires a newer version of Geany (API >= v%d).", name, plugin_version_code); ret = FALSE; g_free(name); } return ret; } static void add_callbacks(Plugin *plugin, PluginCallback *callbacks) { PluginCallback *cb; guint i, len = 0; while (TRUE) { cb = &callbacks[len]; if (!cb->signal_name || !cb->callback) break; len++; } if (len == 0) return; for (i = 0; i < len; i++) { cb = &callbacks[i]; /* Pass the callback data as default user_data if none was set by the plugin itself */ plugin_signal_connect(&plugin->public, NULL, cb->signal_name, cb->after, cb->callback, cb->user_data ? cb->user_data : plugin->cb_data); } } static gint cmp_plugin_names(gconstpointer a, gconstpointer b) { const Plugin *pa = a; const Plugin *pb = b; return strcmp(pa->info.name, pb->info.name); } /** Register a plugin to Geany. * * The plugin will show up in the plugin manager. The user can interact with * it based on the functions it provides and installed GUI elements. * * You must initialize the info and funcs fields of @ref GeanyPlugin * appropriately prior to calling this, otherwise registration will fail. For * info at least a valid name must be set (possibly localized). For funcs, * at least init() and cleanup() functions must be implemented and set. * * The return value must be checked. It may be FALSE if the plugin failed to register which can * mainly happen for two reasons (future Geany versions may add new failure conditions): * - Not all mandatory fields of GeanyPlugin have been set. * - The ABI or API versions reported by the plugin are incompatible with the running Geany. * * Do not call this directly. Use GEANY_PLUGIN_REGISTER() instead which automatically * handles @a api_version and @a abi_version. * * @param plugin The plugin provided by Geany * @param api_version The API version the plugin is compiled against (pass GEANY_API_VERSION) * @param min_api_version The minimum API version required by the plugin * @param abi_version The exact ABI version the plugin is compiled against (pass GEANY_ABI_VERSION) * * @return TRUE if the plugin was successfully registered. Otherwise FALSE. * * @since 1.26 (API 225) * @see GEANY_PLUGIN_REGISTER() **/ GEANY_API_SYMBOL gboolean geany_plugin_register(GeanyPlugin *plugin, gint api_version, gint min_api_version, gint abi_version) { Plugin *p; GeanyPluginFuncs *cbs = plugin->funcs; g_return_val_if_fail(plugin != NULL, FALSE); p = plugin->priv; /* already registered successfully */ g_return_val_if_fail(!PLUGIN_LOADED_OK(p), FALSE); /* Prevent registering incompatible plugins. */ if (! plugin_check_version(p, PLUGIN_VERSION_CODE(api_version, abi_version))) return FALSE; /* Only init and cleanup callbacks are truly mandatory. */ if (! cbs->init || ! cbs->cleanup) { gchar *name = g_path_get_basename(p->filename); geany_debug("Plugin '%s' has no %s function - ignoring plugin!", name, cbs->init ? "cleanup" : "init"); g_free(name); } else { /* Yes, name is checked again later on, however we want return FALSE here * to signal the error back to the plugin (but we don't print the message twice) */ if (! EMPTY(p->info.name)) p->flags = LOADED_OK; } /* If it ever becomes necessary we can save the api version in Plugin * and apply compat code on a per-plugin basis, because we learn about * the requested API version here. For now it's not necessary. */ return PLUGIN_LOADED_OK(p); } /** Register a plugin to Geany, with plugin-defined data. * * This is a variant of geany_plugin_register() that also allows to set the plugin-defined data. * Refer to that function for more details on registering in general. * * @p pdata is the pointer going to be passed to the individual plugin callbacks * of GeanyPlugin::funcs. When the plugin module is unloaded, @p free_func is invoked on * @p pdata, which connects the data to the plugin's module life time. * * You cannot use geany_plugin_set_data() after registering with this function. Use * geany_plugin_register() if you need to. * * Do not call this directly. Use GEANY_PLUGIN_REGISTER_FULL() instead which automatically * handles @p api_version and @p abi_version. * * @param plugin The plugin provided by Geany. * @param api_version The API version the plugin is compiled against (pass GEANY_API_VERSION). * @param min_api_version The minimum API version required by the plugin. * @param abi_version The exact ABI version the plugin is compiled against (pass GEANY_ABI_VERSION). * @param pdata Pointer to the plugin-defined data. Must not be @c NULL. * @param free_func Function used to deallocate @a pdata, may be @c NULL. * * @return TRUE if the plugin was successfully registered. Otherwise FALSE. * * @since 1.26 (API 225) * @see GEANY_PLUGIN_REGISTER_FULL() * @see geany_plugin_register() **/ GEANY_API_SYMBOL gboolean geany_plugin_register_full(GeanyPlugin *plugin, gint api_version, gint min_api_version, gint abi_version, gpointer pdata, GDestroyNotify free_func) { if (geany_plugin_register(plugin, api_version, min_api_version, abi_version)) { geany_plugin_set_data(plugin, pdata, free_func); /* We use LOAD_DATA to indicate that pdata cb_data was set during loading/registration * as opposed to during GeanyPluginFuncs::init(). In the latter case we call free_func * after GeanyPluginFuncs::cleanup() */ plugin->priv->flags |= LOAD_DATA; return TRUE; } return FALSE; } struct LegacyRealFuncs { void (*init) (GeanyData *data); GtkWidget* (*configure) (GtkDialog *dialog); void (*help) (void); void (*cleanup) (void); }; /* Wrappers to support legacy plugins are below */ static gboolean legacy_init(GeanyPlugin *plugin, gpointer pdata) { struct LegacyRealFuncs *h = pdata; h->init(plugin->geany_data); return TRUE; } static void legacy_cleanup(GeanyPlugin *plugin, gpointer pdata) { struct LegacyRealFuncs *h = pdata; /* Can be NULL because it's optional for legacy plugins */ if (h->cleanup) h->cleanup(); } static void legacy_help(GeanyPlugin *plugin, gpointer pdata) { struct LegacyRealFuncs *h = pdata; h->help(); } static GtkWidget *legacy_configure(GeanyPlugin *plugin, GtkDialog *parent, gpointer pdata) { struct LegacyRealFuncs *h = pdata; return h->configure(parent); } static void free_legacy_cbs(gpointer data) { g_slice_free(struct LegacyRealFuncs, data); } /* This function is the equivalent of geany_plugin_register() for legacy-style * plugins which we continue to load for the time being. */ static void register_legacy_plugin(Plugin *plugin, GModule *module) { gint (*p_version_check) (gint abi_version); void (*p_set_info) (PluginInfo *info); void (*p_init) (GeanyData *geany_data); GeanyData **p_geany_data; struct LegacyRealFuncs *h; #define CHECK_FUNC(__x) \ if (! g_module_symbol(module, "plugin_" #__x, (void *) (&p_##__x))) \ { \ geany_debug("Plugin \"%s\" has no plugin_" #__x "() function - ignoring plugin!", \ g_module_name(module)); \ return; \ } CHECK_FUNC(version_check); CHECK_FUNC(set_info); CHECK_FUNC(init); #undef CHECK_FUNC /* We must verify the version first. If the plugin has become incompatible any * further actions should be considered invalid and therefore skipped. */ if (! plugin_check_version(plugin, p_version_check(GEANY_ABI_VERSION))) return; h = g_slice_new(struct LegacyRealFuncs); /* Since the version check passed we can proceed with setting basic fields and * calling its set_info() (which might want to call Geany functions already). */ g_module_symbol(module, "geany_data", (void *) &p_geany_data); if (p_geany_data) *p_geany_data = &geany_data; /* Read plugin name, etc. name is mandatory but that's enforced in the common code. */ p_set_info(&plugin->info); /* If all went well we can set the remaining callbacks and let it go for good. */ h->init = p_init; g_module_symbol(module, "plugin_configure", (void *) &h->configure); g_module_symbol(module, "plugin_configure_single", (void *) &plugin->configure_single); g_module_symbol(module, "plugin_help", (void *) &h->help); g_module_symbol(module, "plugin_cleanup", (void *) &h->cleanup); /* pointer to callbacks struct can be stored directly, no wrapper necessary */ g_module_symbol(module, "plugin_callbacks", (void *) &plugin->cbs.callbacks); if (app->debug_mode) { if (h->configure && plugin->configure_single) g_warning("Plugin '%s' implements plugin_configure_single() unnecessarily - " "only plugin_configure() will be used!", plugin->info.name); if (h->cleanup == NULL) g_warning("Plugin '%s' has no plugin_cleanup() function - there may be memory leaks!", plugin->info.name); } plugin->cbs.init = legacy_init; plugin->cbs.cleanup = legacy_cleanup; plugin->cbs.configure = h->configure ? legacy_configure : NULL; plugin->cbs.help = h->help ? legacy_help : NULL; plugin->flags = LOADED_OK | IS_LEGACY; geany_plugin_set_data(&plugin->public, h, free_legacy_cbs); } static gboolean plugin_load(Plugin *plugin) { gboolean init_ok = TRUE; /* Start the plugin. Legacy plugins require additional cruft. */ if (PLUGIN_IS_LEGACY(plugin) && plugin->proxy == &builtin_so_proxy_plugin) { GeanyPlugin **p_geany_plugin; PluginInfo **p_info; GModule *module = plugin->proxy_data; /* set these symbols before plugin_init() is called * we don't set geany_data since it is set directly by plugin_new() */ g_module_symbol(module, "geany_plugin", (void *) &p_geany_plugin); if (p_geany_plugin) *p_geany_plugin = &plugin->public; g_module_symbol(module, "plugin_info", (void *) &p_info); if (p_info) *p_info = &plugin->info; /* Legacy plugin_init() cannot fail. */ plugin->cbs.init(&plugin->public, plugin->cb_data); } else { init_ok = plugin->cbs.init(&plugin->public, plugin->cb_data); } if (! init_ok) return FALSE; /* new-style plugins set their callbacks in geany_load_module() */ if (plugin->cbs.callbacks) add_callbacks(plugin, plugin->cbs.callbacks); /* remember which plugins are active. * keep list sorted so tools menu items and plugin preference tabs are * sorted by plugin name */ active_plugin_list = g_list_insert_sorted(active_plugin_list, plugin, cmp_plugin_names); proxied_count_inc(plugin->proxy); geany_debug("Loaded: %s (%s)", plugin->filename, plugin->info.name); return TRUE; } static gpointer plugin_load_gmodule(GeanyPlugin *proxy, GeanyPlugin *subplugin, const gchar *fname, gpointer pdata) { GModule *module; void (*p_geany_load_module)(GeanyPlugin *); g_return_val_if_fail(g_module_supported(), NULL); /* Don't use G_MODULE_BIND_LAZY otherwise we can get unresolved symbols at runtime, * causing a segfault. Without that flag the module will safely fail to load. * G_MODULE_BIND_LOCAL also helps find undefined symbols e.g. app when it would * otherwise not be detected due to the shadowing of Geany's app variable. * Also without G_MODULE_BIND_LOCAL calling public functions e.g. the old info() * function from a plugin will be shadowed. */ module = g_module_open(fname, G_MODULE_BIND_LOCAL); if (!module) { geany_debug("Can't load plugin: %s", g_module_error()); return NULL; } /*geany_debug("Initializing plugin '%s'", plugin->info.name);*/ g_module_symbol(module, "geany_load_module", (void *) &p_geany_load_module); if (p_geany_load_module) { /* set this here already so plugins can call i.e. plugin_module_make_resident() * right from their geany_load_module() */ subplugin->priv->proxy_data = module; /* This is a new style plugin. It should fill in plugin->info and then call * geany_plugin_register() in its geany_load_module() to successfully load. * The ABI and API checks are performed by geany_plugin_register() (i.e. by us). * We check the LOADED_OK flag separately to protect us against buggy plugins * who ignore the result of geany_plugin_register() and register anyway */ p_geany_load_module(subplugin); } else { /* This is the legacy / deprecated code path. It does roughly the same as * geany_load_module() and geany_plugin_register() together for the new ones */ register_legacy_plugin(subplugin->priv, module); } /* We actually check the LOADED_OK flag later */ return module; } static void plugin_unload_gmodule(GeanyPlugin *proxy, GeanyPlugin *subplugin, gpointer load_data, gpointer pdata) { GModule *module = (GModule *) load_data; g_return_if_fail(module != NULL); if (! g_module_close(module)) g_warning("%s: %s", subplugin->priv->filename, g_module_error()); } /* Load and optionally init a plugin. * load_plugin decides whether the plugin's plugin_init() function should be called or not. If it is * called, the plugin will be started, if not the plugin will be read only (for the list of * available plugins in the plugin manager). * When add_to_list is set, the plugin will be added to the plugin manager's plugin_list. */ static Plugin* plugin_new(Plugin *proxy, const gchar *fname, gboolean load_plugin, gboolean add_to_list) { Plugin *plugin; g_return_val_if_fail(fname, NULL); g_return_val_if_fail(proxy, NULL); /* find the plugin in the list of already loaded, active plugins and use it, otherwise * load the module */ plugin = find_active_plugin_by_name(fname); if (plugin != NULL) { geany_debug("Plugin \"%s\" already loaded.", fname); if (add_to_list) { /* do not add to the list twice */ if (g_list_find(plugin_list, plugin) != NULL) return NULL; plugin_list = g_list_prepend(plugin_list, plugin); } return plugin; } plugin = g_new0(Plugin, 1); plugin->filename = g_strdup(fname); plugin->proxy = proxy; plugin->public.geany_data = &geany_data; plugin->public.priv = plugin; /* Fields of plugin->info/funcs must to be initialized by the plugin */ plugin->public.info = &plugin->info; plugin->public.funcs = &plugin->cbs; plugin->public.proxy_funcs = &plugin->proxy_cbs; if (plugin_loaded(plugin)) { geany_debug("Plugin \"%s\" already loaded.", fname); goto err; } /* Load plugin, this should read its name etc. It must also call * geany_plugin_register() for the following PLUGIN_LOADED_OK condition */ plugin->proxy_data = proxy->proxy_cbs.load(&proxy->public, &plugin->public, fname, proxy->cb_data); if (! PLUGIN_LOADED_OK(plugin)) { geany_debug("Failed to load \"%s\" - ignoring plugin!", fname); goto err; } /* The proxy assumes success, therefore we have to call unload from here * on in case of errors */ if (EMPTY(plugin->info.name)) { geany_debug("No plugin name set for \"%s\" - ignoring plugin!", fname); goto err_unload; } /* cb_data_destroy() frees plugin->cb_data. If that pointer also passed to unload() afterwards * then that would become a use-after-free. Disallow this combination. If a proxy * needs the same pointer it must not use a destroy func but free manually in its unload(). */ if (plugin->proxy_data == proxy->cb_data && plugin->cb_data_destroy) { geany_debug("Proxy of plugin \"%s\" specified invalid data - ignoring plugin!", fname); plugin->proxy_data = NULL; goto err_unload; } if (load_plugin && !plugin_load(plugin)) { /* Handle failing init same as failing to load for now. In future we * could present a informational UI or something */ geany_debug("Plugin failed to initialize \"%s\" - ignoring plugin!", fname); goto err_unload; } if (add_to_list) plugin_list = g_list_prepend(plugin_list, plugin); return plugin; err_unload: if (plugin->cb_data_destroy) plugin->cb_data_destroy(plugin->cb_data); proxy->proxy_cbs.unload(&proxy->public, &plugin->public, plugin->proxy_data, proxy->cb_data); err: g_free(plugin->filename); g_free(plugin); return NULL; } static void on_object_weak_notify(gpointer data, GObject *old_ptr) { Plugin *plugin = data; guint i = 0; g_return_if_fail(plugin && plugin->signal_ids); for (i = 0; i < plugin->signal_ids->len; i++) { SignalConnection *sc = &g_array_index(plugin->signal_ids, SignalConnection, i); if (sc->object == old_ptr) { g_array_remove_index_fast(plugin->signal_ids, i); /* we can break the loop right after finding the first match, * because we will get one notification per connected signal */ break; } } } /* add an object to watch for destruction, and release pointers to it when destroyed. * this should only be used by plugin_signal_connect() to add a watch on * the object lifetime and nuke out references to it in plugin->signal_ids */ void plugin_watch_object(Plugin *plugin, gpointer object) { g_object_weak_ref(object, on_object_weak_notify, plugin); } static void remove_callbacks(Plugin *plugin) { GArray *signal_ids = plugin->signal_ids; SignalConnection *sc; if (signal_ids == NULL) return; foreach_array(SignalConnection, sc, signal_ids) { g_signal_handler_disconnect(sc->object, sc->handler_id); g_object_weak_unref(sc->object, on_object_weak_notify, plugin); } g_array_free(signal_ids, TRUE); } static void remove_sources(Plugin *plugin) { GList *item; item = plugin->sources; while (item != NULL) { GList *next = item->next; /* cache the next pointer because current item will be freed */ g_source_destroy(item->data); item = next; } /* don't free the list here, it is allocated inside each source's data */ } /* Make the GModule backing plugin resident (if it's GModule-backed at all) */ void plugin_make_resident(Plugin *plugin) { if (plugin->proxy == &builtin_so_proxy_plugin) { g_return_if_fail(plugin->proxy_data != NULL); g_module_make_resident(plugin->proxy_data); } else g_warning("Skipping g_module_make_resident() for non-native plugin"); } /* Retrieve the address of a symbol sym located in plugin, if it's GModule-backed */ gpointer plugin_get_module_symbol(Plugin *plugin, const gchar *sym) { gpointer symbol; if (plugin->proxy == &builtin_so_proxy_plugin) { g_return_val_if_fail(plugin->proxy_data != NULL, NULL); if (g_module_symbol(plugin->proxy_data, sym, &symbol)) return symbol; else g_warning("Failed to locate signal handler for '%s': %s", sym, g_module_error()); } else /* TODO: Could possibly support this via a new proxy hook */ g_warning("Failed to locate signal handler for '%s': Not supported for non-native plugins", sym); return NULL; } static gboolean is_active_plugin(Plugin *plugin) { return (g_list_find(active_plugin_list, plugin) != NULL); } static void remove_each_doc_data(GQuark key_id, gpointer data, gpointer user_data) { const ForEachDocData *doc_data = user_data; const gchar *key = g_quark_to_string(key_id); if (g_str_has_prefix(key, doc_data->prefix)) g_datalist_remove_data(&doc_data->document->priv->data, key); } static void remove_doc_data(Plugin *plugin) { ForEachDocData data; data.prefix = g_strdup_printf("geany/plugins/%s/", plugin->public.info->name); for (guint i = 0; i < documents_array->len; i++) { GeanyDocument *doc = documents_array->pdata[i]; if (DOC_VALID(doc)) { data.document = doc; g_datalist_foreach(&doc->priv->data, remove_each_doc_data, &data); } } g_free(data.prefix); } /* Clean up anything used by an active plugin */ static void plugin_cleanup(Plugin *plugin) { GtkWidget *widget; /* With geany_register_plugin cleanup is mandatory */ plugin->cbs.cleanup(&plugin->public, plugin->cb_data); remove_doc_data(plugin); remove_callbacks(plugin); remove_sources(plugin); if (plugin->key_group) keybindings_free_group(plugin->key_group); widget = plugin->toolbar_separator.widget; if (widget) gtk_widget_destroy(widget); if (!PLUGIN_HAS_LOAD_DATA(plugin) && plugin->cb_data_destroy) { /* If the plugin has used geany_plugin_set_data(), destroy the data here. But don't * if it was already set through geany_plugin_register_full() because we couldn't call * its init() anymore (not without completely reloading it anyway). */ plugin->cb_data_destroy(plugin->cb_data); plugin->cb_data = NULL; plugin->cb_data_destroy = NULL; } proxied_count_dec(plugin->proxy); geany_debug("Unloaded: %s", plugin->filename); } /* Remove all plugins that proxy is a proxy for from plugin_list (and free) */ static void free_subplugins(Plugin *proxy) { GList *item; item = plugin_list; while (item) { GList *next = g_list_next(item); if (proxy == ((Plugin *) item->data)->proxy) { /* plugin_free modifies plugin_list */ plugin_free((Plugin *) item->data); } item = next; } } /* Returns true if the removal was successful (=> never for non-proxies) */ static gboolean unregister_proxy(Plugin *proxy) { gboolean is_proxy = FALSE; GList *node; /* Remove the proxy from the proxy list first. It might appear more than once (once * for each extension), but if it doesn't appear at all it's not actually a proxy */ foreach_list_safe(node, active_proxies.head) { PluginProxy *p = node->data; if (p->plugin == proxy) { is_proxy = TRUE; g_queue_delete_link(&active_proxies, node); } } return is_proxy; } /* Cleanup a plugin and free all resources allocated on behalf of it. * * If the plugin is a proxy then this also takes special care to unload all * subplugin loaded through it (make sure none of them is active!) */ static void plugin_free(Plugin *plugin) { Plugin *proxy; g_return_if_fail(plugin); g_return_if_fail(plugin->proxy); g_return_if_fail(plugin->proxied_count == 0); proxy = plugin->proxy; /* If this a proxy remove all depending subplugins. We can assume none of them is *activated* * (but potentially loaded). Note that free_subplugins() might call us through recursion */ if (is_active_plugin(plugin)) { if (unregister_proxy(plugin)) free_subplugins(plugin); plugin_cleanup(plugin); } active_plugin_list = g_list_remove(active_plugin_list, plugin); plugin_list = g_list_remove(plugin_list, plugin); /* cb_data_destroy might be plugin code and must be called before unloading the module. */ if (plugin->cb_data_destroy) plugin->cb_data_destroy(plugin->cb_data); proxy->proxy_cbs.unload(&proxy->public, &plugin->public, plugin->proxy_data, proxy->cb_data); g_free(plugin->filename); g_free(plugin); } static gchar *get_custom_plugin_path(const gchar *plugin_path_config, const gchar *plugin_path_system) { gchar *plugin_path_custom; if (EMPTY(prefs.custom_plugin_path)) return NULL; plugin_path_custom = utils_get_locale_from_utf8(prefs.custom_plugin_path); utils_tidy_path(plugin_path_custom); /* check whether the custom plugin path is one of the system or user plugin paths * and abort if so */ if (utils_str_equal(plugin_path_custom, plugin_path_config) || utils_str_equal(plugin_path_custom, plugin_path_system)) { g_free(plugin_path_custom); return NULL; } return plugin_path_custom; } /* all 3 paths Geany looks for plugins in can change (even system path on Windows) * so we need to check active plugins are in the right place before loading */ static gboolean check_plugin_path(const gchar *fname) { gchar *plugin_path_config; gchar *plugin_path_system; gchar *plugin_path_custom; gboolean ret = FALSE; plugin_path_config = g_build_filename(app->configdir, "plugins", NULL); if (g_str_has_prefix(fname, plugin_path_config)) ret = TRUE; plugin_path_system = get_plugin_path(); if (g_str_has_prefix(fname, plugin_path_system)) ret = TRUE; plugin_path_custom = get_custom_plugin_path(plugin_path_config, plugin_path_system); if (plugin_path_custom) { if (g_str_has_prefix(fname, plugin_path_custom)) ret = TRUE; g_free(plugin_path_custom); } g_free(plugin_path_config); g_free(plugin_path_system); return ret; } /* Returns NULL if this ain't a plugin, * otherwise it returns the appropriate PluginProxy instance to load it */ static PluginProxy* is_plugin(const gchar *file) { GList *node; const gchar *ext; /* extract file extension to avoid g_str_has_suffix() in the loop */ ext = (const gchar *)strrchr(file, '.'); if (ext == NULL) return FALSE; /* ensure the dot is really part of the filename */ else if (strchr(ext, G_DIR_SEPARATOR) != NULL) return FALSE; ext += 1; /* O(n*m), (m being extensions per proxy) doesn't scale very well in theory * but not a problem in practice yet */ foreach_list(node, active_proxies.head) { PluginProxy *proxy = node->data; if (utils_str_casecmp(ext, proxy->extension) == 0) { Plugin *p = proxy->plugin; gint ret = GEANY_PROXY_MATCH; if (p->proxy_cbs.probe) ret = p->proxy_cbs.probe(&p->public, file, p->cb_data); switch (ret) { case GEANY_PROXY_MATCH: return proxy; case GEANY_PROXY_RELATED: return NULL; case GEANY_PROXY_IGNORE: continue; default: g_warning("Ignoring bogus return value '%d' from " "proxy plugin '%s' probe() function!", ret, proxy->plugin->info.name); continue; } } } return NULL; } /* load active plugins at startup */ static void load_active_plugins(void) { guint i, len, proxies; if (active_plugins_pref == NULL || (len = g_strv_length(active_plugins_pref)) == 0) return; /* If proxys are loaded we have to restart to load plugins that sort before their proxy */ do { proxies = active_proxies.length; g_list_free_full(failed_plugins_list, (GDestroyNotify) g_free); failed_plugins_list = NULL; for (i = 0; i < len; i++) { gchar *fname = active_plugins_pref[i]; #ifdef G_OS_WIN32 /* ensure we have canonical paths */ gchar *p = fname; while ((p = strchr(p, '/')) != NULL) *p = G_DIR_SEPARATOR; #endif if (!EMPTY(fname) && g_file_test(fname, G_FILE_TEST_EXISTS)) { PluginProxy *proxy = NULL; if (check_plugin_path(fname)) proxy = is_plugin(fname); if (proxy == NULL || plugin_new(proxy->plugin, fname, TRUE, FALSE) == NULL) failed_plugins_list = g_list_prepend(failed_plugins_list, g_strdup(fname)); } } } while (proxies != active_proxies.length); } static void load_plugins_from_path(const gchar *path) { GSList *list, *item; gint count = 0; list = utils_get_file_list(path, NULL, NULL); for (item = list; item != NULL; item = g_slist_next(item)) { gchar *fname = g_build_filename(path, item->data, NULL); PluginProxy *proxy = is_plugin(fname); if (proxy != NULL && plugin_new(proxy->plugin, fname, FALSE, TRUE)) count++; g_free(fname); } g_slist_foreach(list, (GFunc) g_free, NULL); g_slist_free(list); if (count) geany_debug("Added %d plugin(s) in '%s'.", count, path); } static gchar *get_plugin_path(void) { return g_strdup(utils_resource_dir(RESOURCE_DIR_PLUGIN)); } /* See load_all_plugins(), this simply sorts items with lower hierarchy level first * (where hierarchy level == number of intermediate proxies before the builtin so loader) */ static gint cmp_plugin_by_proxy(gconstpointer a, gconstpointer b) { const Plugin *pa = a; const Plugin *pb = b; while (TRUE) { if (pa->proxy == pb->proxy) return 0; else if (pa->proxy == &builtin_so_proxy_plugin) return -1; else if (pb->proxy == &builtin_so_proxy_plugin) return 1; pa = pa->proxy; pb = pb->proxy; } } /* Load (but don't initialize) all plugins for the Plugin Manager dialog */ static void load_all_plugins(void) { gchar *plugin_path_config; gchar *plugin_path_system; gchar *plugin_path_custom; plugin_path_config = g_build_filename(app->configdir, "plugins", NULL); plugin_path_system = get_plugin_path(); /* first load plugins in ~/.config/geany/plugins/ */ load_plugins_from_path(plugin_path_config); /* load plugins from a custom path */ plugin_path_custom = get_custom_plugin_path(plugin_path_config, plugin_path_system); if (plugin_path_custom) { load_plugins_from_path(plugin_path_custom); g_free(plugin_path_custom); } /* finally load plugins from $prefix/lib/geany */ load_plugins_from_path(plugin_path_system); /* It is important to sort any plugins that are proxied after their proxy because * pm_populate() needs the proxy to be loaded and active (if selected by user) in order * to properly set the value for the PLUGIN_COLUMN_CAN_UNCHECK column. The order between * sub-plugins does not matter, only between sub-plugins and their proxy, thus * sorting by hierarchy level is perfectly sufficient */ plugin_list = g_list_sort(plugin_list, cmp_plugin_by_proxy); g_free(plugin_path_config); g_free(plugin_path_system); } static void on_tools_menu_show(GtkWidget *menu_item, G_GNUC_UNUSED gpointer user_data) { GList *item, *list = gtk_container_get_children(GTK_CONTAINER(menu_item)); guint i = 0; gboolean have_plugin_menu_items = FALSE; for (item = list; item != NULL; item = g_list_next(item)) { if (item->data == menu_separator) { if (i < g_list_length(list) - 1) { have_plugin_menu_items = TRUE; break; } } i++; } g_list_free(list); ui_widget_show_hide(menu_separator, have_plugin_menu_items); } /* Calling this starts up plugin support */ void plugins_load_active(void) { GtkWidget *widget; want_plugins = TRUE; geany_data_init(); widget = gtk_separator_menu_item_new(); gtk_widget_show(widget); gtk_container_add(GTK_CONTAINER(main_widgets.tools_menu), widget); widget = gtk_menu_item_new_with_mnemonic(_("_Plugin Manager")); gtk_container_add(GTK_CONTAINER(main_widgets.tools_menu), widget); gtk_widget_show(widget); g_signal_connect(widget, "activate", G_CALLBACK(pm_show_dialog), NULL); menu_separator = gtk_separator_menu_item_new(); gtk_container_add(GTK_CONTAINER(main_widgets.tools_menu), menu_separator); g_signal_connect(main_widgets.tools_menu, "show", G_CALLBACK(on_tools_menu_show), NULL); load_active_plugins(); } /* Update the global active plugins list so it's up-to-date when configuration * is saved. Called in response to GeanyObject's "save-settings" signal. */ static void update_active_plugins_pref(void) { gint i = 0; GList *list; gsize count; /* if plugins are disabled, don't clear list of active plugins */ if (!want_plugins) return; count = g_list_length(active_plugin_list) + g_list_length(failed_plugins_list); g_strfreev(active_plugins_pref); if (count == 0) { active_plugins_pref = NULL; return; } active_plugins_pref = g_new0(gchar*, count + 1); for (list = g_list_first(active_plugin_list); list != NULL; list = list->next) { Plugin *plugin = list->data; active_plugins_pref[i] = g_strdup(plugin->filename); i++; } for (list = g_list_first(failed_plugins_list); list != NULL; list = list->next) { const gchar *fname = list->data; active_plugins_pref[i] = g_strdup(fname); i++; } active_plugins_pref[i] = NULL; } /* called even if plugin support is disabled */ void plugins_init(void) { StashGroup *group; gchar *path; path = get_plugin_path(); geany_debug("System plugin path: %s", path); g_free(path); group = stash_group_new("plugins"); configuration_add_session_group(group, TRUE); stash_group_add_toggle_button(group, &prefs.load_plugins, "load_plugins", TRUE, "check_plugins"); stash_group_add_entry(group, &prefs.custom_plugin_path, "custom_plugin_path", "", "extra_plugin_path_entry"); g_signal_connect(geany_object, "save-settings", G_CALLBACK(update_active_plugins_pref), NULL); stash_group_add_string_vector(group, &active_plugins_pref, "active_plugins", NULL); g_queue_push_head(&active_proxies, &builtin_so_proxy); } /* Same as plugin_free(), except it does nothing for proxies-in-use, to be called on * finalize in a loop */ static void plugin_free_leaf(Plugin *p) { if (p->proxied_count == 0) plugin_free(p); } /* called even if plugin support is disabled */ void plugins_finalize(void) { if (failed_plugins_list != NULL) { g_list_foreach(failed_plugins_list, (GFunc) g_free, NULL); g_list_free(failed_plugins_list); } /* Have to loop because proxys cannot be unloaded until after all their * plugins are unloaded as well (the second loop should should catch all the remaining ones) */ while (active_plugin_list != NULL) g_list_foreach(active_plugin_list, (GFunc) plugin_free_leaf, NULL); g_strfreev(active_plugins_pref); } /* Check whether there are any plugins loaded which provide a configure symbol */ gboolean plugins_have_preferences(void) { GList *item; if (active_plugin_list == NULL) return FALSE; foreach_list(item, active_plugin_list) { Plugin *plugin = item->data; if (plugin->configure_single != NULL || plugin->cbs.configure != NULL) return TRUE; } return FALSE; } /* Plugin Manager */ enum { PLUGIN_COLUMN_CHECK = 0, PLUGIN_COLUMN_CAN_UNCHECK, PLUGIN_COLUMN_PLUGIN, PLUGIN_N_COLUMNS, PM_BUTTON_KEYBINDINGS, PM_BUTTON_CONFIGURE, PM_BUTTON_HELP }; typedef struct { GtkWidget *dialog; GtkWidget *tree; GtkTreeStore *store; GtkWidget *filter_entry; GtkWidget *configure_button; GtkWidget *keybindings_button; GtkWidget *help_button; GtkWidget *popup_menu; GtkWidget *popup_configure_menu_item; GtkWidget *popup_keybindings_menu_item; GtkWidget *popup_help_menu_item; } PluginManagerWidgets; static PluginManagerWidgets pm_widgets; static void pm_update_buttons(Plugin *p) { gboolean has_configure = FALSE; gboolean has_help = FALSE; gboolean has_keybindings = FALSE; if (p != NULL && is_active_plugin(p)) { has_configure = p->cbs.configure || p->configure_single; has_help = p->cbs.help != NULL; has_keybindings = p->key_group && p->key_group->plugin_key_count; } gtk_widget_set_sensitive(pm_widgets.configure_button, has_configure); gtk_widget_set_sensitive(pm_widgets.help_button, has_help); gtk_widget_set_sensitive(pm_widgets.keybindings_button, has_keybindings); gtk_widget_set_sensitive(pm_widgets.popup_configure_menu_item, has_configure); gtk_widget_set_sensitive(pm_widgets.popup_help_menu_item, has_help); gtk_widget_set_sensitive(pm_widgets.popup_keybindings_menu_item, has_keybindings); } static void pm_selection_changed(GtkTreeSelection *selection, gpointer user_data) { GtkTreeIter iter; GtkTreeModel *model; Plugin *p; if (gtk_tree_selection_get_selected(selection, &model, &iter)) { gtk_tree_model_get(model, &iter, PLUGIN_COLUMN_PLUGIN, &p, -1); if (p != NULL) pm_update_buttons(p); } } static gboolean find_iter_for_plugin(Plugin *p, GtkTreeModel *model, GtkTreeIter *iter) { Plugin *pp; gboolean valid; for (valid = gtk_tree_model_get_iter_first(model, iter); valid; valid = gtk_tree_model_iter_next(model, iter)) { gtk_tree_model_get(model, iter, PLUGIN_COLUMN_PLUGIN, &pp, -1); if (p == pp) return TRUE; } return FALSE; } static void pm_populate(GtkTreeStore *store); static void pm_plugin_toggled(GtkCellRendererToggle *cell, gchar *pth, gpointer data) { gboolean old_state, state; gchar *file_name; GtkTreeIter iter; GtkTreeIter store_iter; GtkTreePath *path = gtk_tree_path_new_from_string(pth); GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(pm_widgets.tree)); Plugin *p; Plugin *proxy; guint prev_num_proxies; gtk_tree_model_get_iter(model, &iter, path); gtk_tree_model_get(model, &iter, PLUGIN_COLUMN_CHECK, &old_state, PLUGIN_COLUMN_PLUGIN, &p, -1); /* no plugins item */ if (p == NULL) { gtk_tree_path_free(path); return; } gtk_tree_model_filter_convert_iter_to_child_iter( GTK_TREE_MODEL_FILTER(model), &store_iter, &iter); state = ! old_state; /* toggle the state */ /* save the filename and proxy of the plugin */ file_name = g_strdup(p->filename); proxy = p->proxy; prev_num_proxies = active_proxies.length; /* unload plugin module */ if (!state) /* save shortcuts (only need this group, but it doesn't take long) */ keybindings_write_to_file(); /* plugin_new() below may cause a tree view refresh with invalid p - set to NULL */ gtk_tree_store_set(pm_widgets.store, &store_iter, PLUGIN_COLUMN_PLUGIN, NULL, -1); plugin_free(p); /* reload plugin module and initialize it if item is checked */ p = plugin_new(proxy, file_name, state, TRUE); if (!p) { /* plugin file may no longer be on disk, or is now incompatible */ gtk_tree_store_remove(pm_widgets.store, &store_iter); } else { if (state) keybindings_load_keyfile(); /* load shortcuts */ /* update model */ gtk_tree_store_set(pm_widgets.store, &store_iter, PLUGIN_COLUMN_CHECK, state, PLUGIN_COLUMN_PLUGIN, p, -1); /* set again the sensitiveness of the configure and help buttons */ pm_update_buttons(p); /* Depending on the state disable the checkbox for the proxy of this plugin, and * only re-enable if the proxy is not used by any other plugin */ if (p->proxy != &builtin_so_proxy_plugin) { GtkTreeIter parent; gboolean can_uncheck; GtkTreePath *store_path = gtk_tree_model_filter_convert_path_to_child_path( GTK_TREE_MODEL_FILTER(model), path); g_warn_if_fail(store_path != NULL); if (gtk_tree_path_up(store_path)) { gtk_tree_model_get_iter(GTK_TREE_MODEL(pm_widgets.store), &parent, store_path); if (state) can_uncheck = FALSE; else can_uncheck = p->proxy->proxied_count == 0; gtk_tree_store_set(pm_widgets.store, &parent, PLUGIN_COLUMN_CAN_UNCHECK, can_uncheck, -1); } gtk_tree_path_free(store_path); } } /* We need to find out if a proxy was added or removed because that affects the plugin list * presented by the plugin manager */ if (prev_num_proxies != active_proxies.length) { /* Rescan the plugin list as we now support more. Gives some "already loaded" warnings * they are unproblematic */ if (prev_num_proxies < active_proxies.length) load_all_plugins(); pm_populate(pm_widgets.store); gtk_tree_view_expand_row(GTK_TREE_VIEW(pm_widgets.tree), path, FALSE); } gtk_tree_path_free(path); g_free(file_name); } static void pm_populate(GtkTreeStore *store) { GtkTreeIter iter; GList *list; gtk_tree_store_clear(store); list = g_list_first(plugin_list); if (list == NULL) { gtk_tree_store_append(store, &iter, NULL); gtk_tree_store_set(store, &iter, PLUGIN_COLUMN_CHECK, FALSE, PLUGIN_COLUMN_PLUGIN, NULL, -1); } else { for (; list != NULL; list = list->next) { Plugin *p = list->data; GtkTreeIter parent; if (p->proxy != &builtin_so_proxy_plugin && find_iter_for_plugin(p->proxy, GTK_TREE_MODEL(pm_widgets.store), &parent)) gtk_tree_store_append(store, &iter, &parent); else gtk_tree_store_append(store, &iter, NULL); gtk_tree_store_set(store, &iter, PLUGIN_COLUMN_CHECK, is_active_plugin(p), PLUGIN_COLUMN_PLUGIN, p, PLUGIN_COLUMN_CAN_UNCHECK, (p->proxied_count == 0), -1); } } } static gboolean pm_treeview_query_tooltip(GtkWidget *widget, gint x, gint y, gboolean keyboard_mode, GtkTooltip *tooltip, gpointer user_data) { GtkTreeModel *model; GtkTreeIter iter; GtkTreePath *path; Plugin *p = NULL; gboolean can_uncheck = TRUE; if (! gtk_tree_view_get_tooltip_context(GTK_TREE_VIEW(widget), &x, &y, keyboard_mode, &model, &path, &iter)) return FALSE; gtk_tree_model_get(model, &iter, PLUGIN_COLUMN_PLUGIN, &p, PLUGIN_COLUMN_CAN_UNCHECK, &can_uncheck, -1); if (p != NULL) { gchar *prefix, *suffix, *details, *markup; const gchar *uchk; uchk = can_uncheck ? "" : _("\nOther plugins depend on this. Disable them first to allow deactivation.\n"); /* Four allocations is less than ideal but meh */ details = g_strdup_printf(_("Version:\t%s\nAuthor(s):\t%s\nFilename:\t%s"), p->info.version, p->info.author, p->filename); prefix = g_markup_printf_escaped("%s\n%s\n", p->info.name, p->info.description); suffix = g_markup_printf_escaped("\n%s", details); markup = g_strconcat(prefix, uchk, suffix, NULL); gtk_tooltip_set_markup(tooltip, markup); gtk_tree_view_set_tooltip_row(GTK_TREE_VIEW(widget), tooltip, path); g_free(details); g_free(suffix); g_free(prefix); g_free(markup); } gtk_tree_path_free(path); return p != NULL; } static void pm_treeview_text_cell_data_func(GtkTreeViewColumn *column, GtkCellRenderer *cell, GtkTreeModel *model, GtkTreeIter *iter, gpointer data) { Plugin *p; gtk_tree_model_get(model, iter, PLUGIN_COLUMN_PLUGIN, &p, -1); if (p == NULL) g_object_set(cell, "text", _("No plugins available."), NULL); else { gchar *markup = g_markup_printf_escaped("%s\n%s", p->info.name, p->info.description); g_object_set(cell, "markup", markup, NULL); g_free(markup); } } static gboolean pm_treeview_button_press_cb(GtkWidget *widget, GdkEventButton *event, G_GNUC_UNUSED gpointer user_data) { if (event->button == 3) { gtk_menu_popup_at_pointer(GTK_MENU(pm_widgets.popup_menu), (GdkEvent *) event); } return FALSE; } static gint pm_tree_sort_func(GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer user_data) { Plugin *pa, *pb; gtk_tree_model_get(model, a, PLUGIN_COLUMN_PLUGIN, &pa, -1); gtk_tree_model_get(model, b, PLUGIN_COLUMN_PLUGIN, &pb, -1); if (pa && pb) return strcmp(pa->info.name, pb->info.name); else return pa - pb; } static gboolean pm_tree_search(const gchar *key, const gchar *haystack) { gchar *normalized_string = NULL; gchar *normalized_key = NULL; gchar *case_normalized_string = NULL; gchar *case_normalized_key = NULL; gboolean matched = TRUE; normalized_string = g_utf8_normalize(haystack, -1, G_NORMALIZE_ALL); normalized_key = g_utf8_normalize(key, -1, G_NORMALIZE_ALL); if (normalized_string != NULL && normalized_key != NULL) { GString *stripped_key; gchar **subkey, **subkeys; case_normalized_string = g_utf8_casefold(normalized_string, -1); case_normalized_key = g_utf8_casefold(normalized_key, -1); stripped_key = g_string_new(case_normalized_key); do {} while (utils_string_replace_all(stripped_key, " ", " ")); subkeys = g_strsplit(stripped_key->str, " ", -1); g_string_free(stripped_key, TRUE); foreach_strv(subkey, subkeys) { if (strstr(case_normalized_string, *subkey) == NULL) { matched = FALSE; break; } } g_strfreev(subkeys); } g_free(normalized_key); g_free(normalized_string); g_free(case_normalized_key); g_free(case_normalized_string); return matched; } static gboolean pm_tree_filter_func(GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data) { Plugin *plugin; gboolean matched; const gchar *key; gchar *haystack, *filename; gtk_tree_model_get(model, iter, PLUGIN_COLUMN_PLUGIN, &plugin, -1); if (!plugin) return TRUE; key = gtk_entry_get_text(GTK_ENTRY(pm_widgets.filter_entry)); filename = g_path_get_basename(plugin->filename); haystack = g_strjoin(" ", plugin->info.name, plugin->info.description, plugin->info.author, filename, NULL); matched = pm_tree_search(key, haystack); g_free(haystack); g_free(filename); return matched; } static void on_pm_tree_filter_entry_changed_cb(GtkEntry *entry, gpointer user_data) { GtkTreeModel *filter_model = gtk_tree_view_get_model(GTK_TREE_VIEW(pm_widgets.tree)); gtk_tree_model_filter_refilter(GTK_TREE_MODEL_FILTER(filter_model)); } static void on_pm_tree_filter_entry_icon_release_cb(GtkEntry *entry, GtkEntryIconPosition icon_pos, GdkEvent *event, gpointer user_data) { if (event->button.button == 1 && icon_pos == GTK_ENTRY_ICON_PRIMARY) on_pm_tree_filter_entry_changed_cb(entry, user_data); } static void pm_prepare_treeview(GtkWidget *tree, GtkTreeStore *store) { GtkCellRenderer *text_renderer, *checkbox_renderer; GtkTreeViewColumn *column; GtkTreeModel *filter_model; GtkTreeSelection *sel; g_signal_connect(tree, "query-tooltip", G_CALLBACK(pm_treeview_query_tooltip), NULL); gtk_widget_set_has_tooltip(tree, TRUE); gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(tree), FALSE); checkbox_renderer = gtk_cell_renderer_toggle_new(); column = gtk_tree_view_column_new_with_attributes( _("Active"), checkbox_renderer, "active", PLUGIN_COLUMN_CHECK, "activatable", PLUGIN_COLUMN_CAN_UNCHECK, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(tree), column); g_signal_connect(checkbox_renderer, "toggled", G_CALLBACK(pm_plugin_toggled), NULL); text_renderer = gtk_cell_renderer_text_new(); g_object_set(text_renderer, "ellipsize", PANGO_ELLIPSIZE_END, NULL); column = gtk_tree_view_column_new_with_attributes(_("Plugin"), text_renderer, NULL); gtk_tree_view_column_set_cell_data_func(column, text_renderer, pm_treeview_text_cell_data_func, NULL, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(tree), column); gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(tree), TRUE); gtk_tree_view_set_enable_search(GTK_TREE_VIEW(tree), FALSE); gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(store), PLUGIN_COLUMN_PLUGIN, pm_tree_sort_func, NULL, NULL); gtk_tree_sortable_set_sort_column_id( GTK_TREE_SORTABLE(store), PLUGIN_COLUMN_PLUGIN, GTK_SORT_ASCENDING); /* selection handling */ sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree)); gtk_tree_selection_set_mode(sel, GTK_SELECTION_SINGLE); g_signal_connect(sel, "changed", G_CALLBACK(pm_selection_changed), NULL); g_signal_connect(tree, "button-press-event", G_CALLBACK(pm_treeview_button_press_cb), NULL); /* filter */ filter_model = gtk_tree_model_filter_new(GTK_TREE_MODEL(store), NULL); gtk_tree_model_filter_set_visible_func( GTK_TREE_MODEL_FILTER(filter_model), pm_tree_filter_func, NULL, NULL); /* set model to tree view */ gtk_tree_view_set_model(GTK_TREE_VIEW(tree), filter_model); g_object_unref(filter_model); pm_populate(store); } static void pm_on_plugin_button_clicked(G_GNUC_UNUSED GtkButton *button, gpointer user_data) { GtkTreeModel *model; GtkTreeSelection *selection; GtkTreeIter iter; Plugin *p; selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(pm_widgets.tree)); if (gtk_tree_selection_get_selected(selection, &model, &iter)) { gtk_tree_model_get(model, &iter, PLUGIN_COLUMN_PLUGIN, &p, -1); if (p != NULL) { if (GPOINTER_TO_INT(user_data) == PM_BUTTON_CONFIGURE) plugin_show_configure(&p->public); else if (GPOINTER_TO_INT(user_data) == PM_BUTTON_HELP) { g_return_if_fail(p->cbs.help != NULL); p->cbs.help(&p->public, p->cb_data); } else if (GPOINTER_TO_INT(user_data) == PM_BUTTON_KEYBINDINGS && p->key_group && p->key_group->plugin_key_count > 0) keybindings_dialog_show_prefs_scroll(p->info.name); } } } static void free_non_active_plugin(gpointer data, gpointer user_data) { Plugin *plugin = data; /* don't do anything when closing the plugin manager and it is an active plugin */ if (is_active_plugin(plugin)) return; plugin_free(plugin); } /* Callback when plugin manager dialog closes, responses GTK_RESPONSE_CLOSE and * GTK_RESPONSE_DELETE_EVENT are treated the same. */ static void pm_dialog_response(GtkDialog *dialog, gint response, gpointer user_data) { switch (response) { case GTK_RESPONSE_CLOSE: case GTK_RESPONSE_DELETE_EVENT: if (plugin_list != NULL) { /* remove all non-active plugins from the list */ g_list_foreach(plugin_list, free_non_active_plugin, NULL); g_list_free(plugin_list); plugin_list = NULL; } gtk_widget_destroy(GTK_WIDGET(dialog)); pm_widgets.dialog = NULL; configuration_save(); break; case PM_BUTTON_CONFIGURE: case PM_BUTTON_HELP: case PM_BUTTON_KEYBINDINGS: /* forward event to the generic handler */ pm_on_plugin_button_clicked(NULL, GINT_TO_POINTER(response)); break; } } static void pm_show_dialog(GtkMenuItem *menuitem, gpointer user_data) { GtkWidget *vbox, *vbox2, *swin, *label, *menu_item, *filter_entry; if (pm_widgets.dialog != NULL) { gtk_window_present(GTK_WINDOW(pm_widgets.dialog)); return; } /* before showing the dialog, we need to create the list of available plugins */ load_all_plugins(); pm_widgets.dialog = gtk_dialog_new(); gtk_window_set_title(GTK_WINDOW(pm_widgets.dialog), _("Plugins")); gtk_window_set_transient_for(GTK_WINDOW(pm_widgets.dialog), GTK_WINDOW(main_widgets.window)); gtk_window_set_destroy_with_parent(GTK_WINDOW(pm_widgets.dialog), TRUE); vbox = ui_dialog_vbox_new(GTK_DIALOG(pm_widgets.dialog)); gtk_widget_set_name(pm_widgets.dialog, "GeanyDialog"); gtk_box_set_spacing(GTK_BOX(vbox), 6); gtk_window_set_default_size(GTK_WINDOW(pm_widgets.dialog), 500, 450); pm_widgets.help_button = gtk_dialog_add_button( GTK_DIALOG(pm_widgets.dialog), GTK_STOCK_HELP, PM_BUTTON_HELP); pm_widgets.configure_button = gtk_dialog_add_button( GTK_DIALOG(pm_widgets.dialog), GTK_STOCK_PREFERENCES, PM_BUTTON_CONFIGURE); pm_widgets.keybindings_button = gtk_dialog_add_button( GTK_DIALOG(pm_widgets.dialog), _("Keybindings"), PM_BUTTON_KEYBINDINGS); gtk_dialog_add_button(GTK_DIALOG(pm_widgets.dialog), GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE); gtk_dialog_set_default_response(GTK_DIALOG(pm_widgets.dialog), GTK_RESPONSE_CLOSE); /* filter */ pm_widgets.filter_entry = filter_entry = gtk_entry_new(); gtk_entry_set_icon_from_stock(GTK_ENTRY(filter_entry), GTK_ENTRY_ICON_PRIMARY, GTK_STOCK_FIND); ui_entry_add_clear_icon(GTK_ENTRY(filter_entry)); g_signal_connect(filter_entry, "changed", G_CALLBACK(on_pm_tree_filter_entry_changed_cb), NULL); g_signal_connect(filter_entry, "icon-release", G_CALLBACK(on_pm_tree_filter_entry_icon_release_cb), NULL); /* prepare treeview */ pm_widgets.tree = gtk_tree_view_new(); pm_widgets.store = gtk_tree_store_new( PLUGIN_N_COLUMNS, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_POINTER); pm_prepare_treeview(pm_widgets.tree, pm_widgets.store); gtk_tree_view_expand_all(GTK_TREE_VIEW(pm_widgets.tree)); g_object_unref(pm_widgets.store); swin = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(swin), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(swin), GTK_SHADOW_IN); gtk_container_add(GTK_CONTAINER(swin), pm_widgets.tree); label = geany_wrap_label_new(_("Choose which plugins should be loaded at startup:")); /* plugin popup menu */ pm_widgets.popup_menu = gtk_menu_new(); menu_item = gtk_image_menu_item_new_from_stock(GTK_STOCK_PREFERENCES, NULL); gtk_container_add(GTK_CONTAINER(pm_widgets.popup_menu), menu_item); g_signal_connect(menu_item, "activate", G_CALLBACK(pm_on_plugin_button_clicked), GINT_TO_POINTER(PM_BUTTON_CONFIGURE)); pm_widgets.popup_configure_menu_item = menu_item; menu_item = gtk_image_menu_item_new_with_mnemonic(_("Keybindings")); gtk_container_add(GTK_CONTAINER(pm_widgets.popup_menu), menu_item); g_signal_connect(menu_item, "activate", G_CALLBACK(pm_on_plugin_button_clicked), GINT_TO_POINTER(PM_BUTTON_KEYBINDINGS)); pm_widgets.popup_keybindings_menu_item = menu_item; menu_item = gtk_image_menu_item_new_from_stock(GTK_STOCK_HELP, NULL); gtk_container_add(GTK_CONTAINER(pm_widgets.popup_menu), menu_item); g_signal_connect(menu_item, "activate", G_CALLBACK(pm_on_plugin_button_clicked), GINT_TO_POINTER(PM_BUTTON_HELP)); pm_widgets.popup_help_menu_item = menu_item; /* put it together */ vbox2 = gtk_box_new(GTK_ORIENTATION_VERTICAL, 6); gtk_box_pack_start(GTK_BOX(vbox2), label, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox2), filter_entry, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox2), swin, TRUE, TRUE, 0); g_signal_connect(pm_widgets.dialog, "response", G_CALLBACK(pm_dialog_response), NULL); gtk_box_pack_start(GTK_BOX(vbox), vbox2, TRUE, TRUE, 0); gtk_widget_show_all(pm_widgets.dialog); gtk_widget_show_all(pm_widgets.popup_menu); /* set initial plugin buttons state, pass NULL as no plugin is selected by default */ pm_update_buttons(NULL); gtk_widget_grab_focus(pm_widgets.filter_entry); } /** Register the plugin as a proxy for other plugins * * Proxy plugins register a list of file extensions and a set of callbacks that are called * appropriately. A plugin can be a proxy for multiple types of sub-plugins by handling * separate file extensions, however they must share the same set of hooks, because this * function can only be called at most once per plugin. * * Each callback receives the plugin-defined data as parameter (see geany_plugin_register()). The * callbacks must be set prior to calling this, by assigning to @a plugin->proxy_funcs. * GeanyProxyFuncs::load and GeanyProxyFuncs::unload must be implemented. * * Nested proxies are unsupported at this point (TODO). * * @note It is entirely up to the proxy to provide access to Geany's plugin API. Native code * can naturally call Geany's API directly, for interpreted languages the proxy has to * implement some kind of bindings that the plugin can use. * * @see proxy for detailed documentation and an example. * * @param plugin The pointer to the plugin's GeanyPlugin instance * @param extensions A @c NULL-terminated string array of file extensions, excluding the dot. * @return @c TRUE if the proxy was successfully registered, otherwise @c FALSE * * @since 1.26 (API 226) */ GEANY_API_SYMBOL gboolean geany_plugin_register_proxy(GeanyPlugin *plugin, const gchar **extensions) { Plugin *p; const gchar **ext; PluginProxy *proxy; GList *node; g_return_val_if_fail(plugin != NULL, FALSE); g_return_val_if_fail(extensions != NULL, FALSE); g_return_val_if_fail(*extensions != NULL, FALSE); g_return_val_if_fail(plugin->proxy_funcs->load != NULL, FALSE); g_return_val_if_fail(plugin->proxy_funcs->unload != NULL, FALSE); p = plugin->priv; /* Check if this was called already. We want to reserve for the use case of calling * this again to set new supported extensions (for example, based on proxy configuration). */ foreach_list(node, active_proxies.head) { proxy = node->data; g_return_val_if_fail(p != proxy->plugin, FALSE); } foreach_strv(ext, extensions) { if (**ext == '.') { g_warning(_("Proxy plugin '%s' extension '%s' starts with a dot. " "Please fix your proxy plugin."), p->info.name, *ext); } proxy = g_new(PluginProxy, 1); g_strlcpy(proxy->extension, *ext, sizeof(proxy->extension)); proxy->plugin = p; /* prepend, so that plugins automatically override core providers for a given extension */ g_queue_push_head(&active_proxies, proxy); } return TRUE; } #endif geany-2.0/src/win32.c0000644000175000017500000003716114514252267011314 00000000000000/* * win32.c - this file is part of Geany, a fast and lightweight IDE * * Copyright 2005 The Geany contributors * * This program 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; either version 2 of the License, or * (at your option) any later version. * * This program 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /* * Special functions for the win32 platform, to provide native dialogs. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif /* Need Windows XP for SHGetFolderPathAndSubDirW */ #define _WIN32_WINNT 0x0501 /* Needed for SHGFP_TYPE */ #define _WIN32_IE 0x0500 #include "win32.h" #ifdef G_OS_WIN32 #include "dialogs.h" #include "document.h" #include "editor.h" #include "filetypes.h" #include "project.h" #include "support.h" #include "ui_utils.h" #include "utils.h" #include #include #include #include #include #include #include #include #include #include #include #include /* The timer handle used to refresh windows below modal native dialogs. If * ever more than one dialog can be shown at a time, this needs to be changed * to be for specific dialogs. */ static UINT_PTR dialog_timer = 0; G_INLINE_FUNC void win32_dialog_reset_timer(HWND hwnd) { if (G_UNLIKELY(dialog_timer != 0)) { KillTimer(hwnd, dialog_timer); dialog_timer = 0; } } static VOID CALLBACK win32_dialog_update_main_window(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime) { gint i; /* Pump the main window loop a bit, but not enough to lock-up. * The typical `while(gtk_events_pending()) gtk_main_iteration();` * loop causes the entire operating system to lock-up. */ for (i = 0; i < 4 && gtk_events_pending(); i++) gtk_main_iteration(); /* Cancel any pending timers since we just did an update */ win32_dialog_reset_timer(hwnd); } G_INLINE_FUNC UINT_PTR win32_dialog_queue_main_window_redraw(HWND dlg, UINT msg, WPARAM wParam, LPARAM lParam, gboolean postpone) { switch (msg) { /* Messages that likely mean the window below a dialog needs to be re-drawn. */ case WM_WINDOWPOSCHANGED: case WM_MOVE: case WM_SIZE: case WM_THEMECHANGED: if (postpone) { win32_dialog_reset_timer(dlg); dialog_timer = SetTimer(dlg, 0, 33 /* around 30fps */, win32_dialog_update_main_window); } else win32_dialog_update_main_window(dlg, msg, wParam, lParam); break; } return 0; /* always let the default proc handle it */ } /* This function is called for OPENFILENAME lpfnHook function and it establishes * a timer that is reset each time which will update the main window loop eventually. */ static UINT_PTR CALLBACK win32_dialog_explorer_hook_proc(HWND dlg, UINT msg, WPARAM wParam, LPARAM lParam) { return win32_dialog_queue_main_window_redraw(dlg, msg, wParam, lParam, TRUE); } /* This function is called for old-school win32 dialogs that accept a proper * lpfnHook function for all messages, it doesn't use a timer. */ static UINT_PTR CALLBACK win32_dialog_hook_proc(HWND dlg, UINT msg, WPARAM wParam, LPARAM lParam) { return win32_dialog_queue_main_window_redraw(dlg, msg, wParam, lParam, FALSE); } /* Converts the given UTF-8 filename or directory name into something usable for Windows and * returns the directory part of the given filename. */ static wchar_t *get_dir_for_path(const gchar *utf8_filename) { static wchar_t w_dir[MAX_PATH]; gchar *result; if (g_file_test(utf8_filename, G_FILE_TEST_IS_DIR)) result = (gchar*) utf8_filename; else result = g_path_get_dirname(utf8_filename); MultiByteToWideChar(CP_UTF8, 0, result, -1, w_dir, G_N_ELEMENTS(w_dir)); if (result != utf8_filename) g_free(result); return w_dir; } /* Callback function for setting the initial directory of the folder open dialog. This could also * be done with BROWSEINFO.pidlRoot and SHParseDisplayName but SHParseDisplayName is not available * on systems below Windows XP. So, we go the hard way by creating a callback which will set up the * folder when the dialog is initialised. Yeah, I like Windows. */ static INT CALLBACK BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM lp, LPARAM pData) { win32_dialog_hook_proc(hwnd, uMsg, lp, pData); switch (uMsg) { case BFFM_INITIALIZED: { SendMessageW(hwnd, BFFM_SETSELECTIONW, TRUE, pData); break; } case BFFM_SELCHANGED: { /* set the status window to the currently selected path. */ static wchar_t szDir[MAX_PATH]; if (SHGetPathFromIDListW((LPITEMIDLIST) lp, szDir)) { SendMessageW(hwnd, BFFM_SETSTATUSTEXTW, 0, (LPARAM) szDir); } break; } } return 0; } /* Shows a folder selection dialog. * initial_dir is expected in UTF-8 * The selected folder name is returned. */ gchar *win32_show_folder_dialog(GtkWidget *parent, const gchar *title, const gchar *initial_dir) { BROWSEINFOW bi; LPITEMIDLIST pidl; gchar *result = NULL; wchar_t fname[MAX_PATH]; wchar_t w_title[512]; MultiByteToWideChar(CP_UTF8, 0, title, -1, w_title, G_N_ELEMENTS(w_title)); if (parent == NULL) parent = main_widgets.window; memset(&bi, 0, sizeof bi); bi.hwndOwner = GDK_WINDOW_HWND(gtk_widget_get_window(parent)); bi.pidlRoot = NULL; bi.lpszTitle = w_title; bi.lpfn = BrowseCallbackProc; bi.lParam = (LPARAM) get_dir_for_path(initial_dir); bi.ulFlags = BIF_DONTGOBELOWDOMAIN | BIF_RETURNONLYFSDIRS | BIF_STATUSTEXT | BIF_USENEWUI; pidl = SHBrowseForFolderW(&bi); /* convert the strange Windows folder list item something into an usual path string ;-) */ if (pidl != NULL) { if (SHGetPathFromIDListW(pidl, fname)) { result = g_malloc0(MAX_PATH * 2); WideCharToMultiByte(CP_UTF8, 0, fname, -1, result, MAX_PATH * 2, NULL, NULL); } CoTaskMemFree(pidl); } return result; } /* initial_dir can be NULL to use the current working directory. * Returns: the selected filename */ gchar *win32_show_file_dialog(GtkWindow *parent, const gchar *title, const gchar *initial_file) { OPENFILENAMEW of; gint retval; gchar tmp[MAX_PATH]; wchar_t w_file[MAX_PATH]; wchar_t w_title[512]; w_file[0] = '\0'; if (initial_file != NULL) MultiByteToWideChar(CP_UTF8, 0, initial_file, -1, w_file, G_N_ELEMENTS(w_file)); MultiByteToWideChar(CP_UTF8, 0, title, -1, w_title, G_N_ELEMENTS(w_title)); /* initialise file dialog info struct */ memset(&of, 0, sizeof of); of.lStructSize = sizeof of; of.hwndOwner = GDK_WINDOW_HWND(gtk_widget_get_window(GTK_WIDGET(parent))); of.lpstrFile = w_file; of.nMaxFile = 2048; of.lpstrFileTitle = NULL; of.lpstrTitle = w_title; of.lpstrDefExt = L""; of.Flags = OFN_FILEMUSTEXIST | OFN_EXPLORER | OFN_ENABLEHOOK | OFN_ENABLESIZING; of.lpfnHook = win32_dialog_explorer_hook_proc; retval = GetOpenFileNameW(&of); if (! retval) { if (CommDlgExtendedError()) { gchar *error = g_strdup_printf( "File dialog box error (%x)", (gint) CommDlgExtendedError()); win32_message_dialog(NULL, GTK_MESSAGE_ERROR, error); g_free(error); } return NULL; } WideCharToMultiByte(CP_UTF8, 0, w_file, -1, tmp, sizeof(tmp), NULL, NULL); return g_strdup(tmp); } /* Creates a native Windows message box of the given type and returns always TRUE * or FALSE representing th pressed Yes or No button. * If type is not GTK_MESSAGE_QUESTION, it returns always TRUE. */ gboolean win32_message_dialog(GtkWidget *parent, GtkMessageType type, const gchar *msg) { gboolean ret = TRUE; gint rc; guint t; const gchar *title; HWND parent_hwnd = NULL; static wchar_t w_msg[512]; static wchar_t w_title[512]; switch (type) { case GTK_MESSAGE_ERROR: { t = MB_OK | MB_ICONERROR; title = _("Error"); break; } case GTK_MESSAGE_QUESTION: { t = MB_YESNO | MB_ICONQUESTION; title = _("Question"); break; } case GTK_MESSAGE_WARNING: { t = MB_OK | MB_ICONWARNING; title = _("Warning"); break; } default: { t = MB_OK | MB_ICONINFORMATION; title = _("Information"); break; } } /* convert the Unicode chars to wide chars */ /** TODO test if LANG == C then possibly skip conversion => g_win32_getlocale() */ MultiByteToWideChar(CP_UTF8, 0, msg, -1, w_msg, G_N_ELEMENTS(w_msg)); MultiByteToWideChar(CP_UTF8, 0, title, -1, w_title, G_N_ELEMENTS(w_title)); if (parent != NULL) parent_hwnd = GDK_WINDOW_HWND(gtk_widget_get_window(parent)); else if (main_widgets.window != NULL) parent_hwnd = GDK_WINDOW_HWND(gtk_widget_get_window(main_widgets.window)); /* display the message box */ rc = MessageBoxW(parent_hwnd, w_msg, w_title, t); if (type == GTK_MESSAGE_QUESTION && rc != IDYES) ret = FALSE; return ret; } /* Little wrapper for _waccess(), returns errno or 0 if there was no error */ gint win32_check_write_permission(const gchar *dir) { static wchar_t w_dir[MAX_PATH]; MultiByteToWideChar(CP_UTF8, 0, dir, -1, w_dir, G_N_ELEMENTS(w_dir)); if (_waccess(w_dir, R_OK | W_OK) != 0) return errno; else return 0; } /* Just a simple wrapper function to open a browser window */ void win32_open_browser(const gchar *uri) { gint ret; if (strncmp(uri, "file://", 7) == 0) { uri += 7; if (strchr(uri, ':') != NULL) { while (*uri == '/') uri++; } } ret = (gint) ShellExecute(NULL, "open", uri, NULL, NULL, SW_SHOWNORMAL); if (ret <= 32) { gchar *err = g_win32_error_message(GetLastError()); ui_set_statusbar(TRUE, _("Failed to open URI \"%s\": %s"), uri, err); g_warning("ShellExecute failed opening \"%s\" (code %d): %s", uri, ret, err); g_free(err); } } static FILE *open_std_handle(DWORD handle, const char *mode) { HANDLE lStdHandle; int hConHandle; FILE *fp; lStdHandle = GetStdHandle(handle); if (lStdHandle == INVALID_HANDLE_VALUE) { gchar *err = g_win32_error_message(GetLastError()); g_warning("GetStdHandle(%ld) failed: %s", (long)handle, err); g_free(err); return NULL; } hConHandle = _open_osfhandle((intptr_t)lStdHandle, _O_TEXT); if (hConHandle == -1) { gchar *err = g_win32_error_message(GetLastError()); g_warning("_open_osfhandle(handle(%ld), _O_TEXT) failed: %s", (long)handle, err); g_free(err); return NULL; } fp = _fdopen(hConHandle, mode); if (! fp) { gchar *err = g_win32_error_message(GetLastError()); g_warning("_fdopen(%d, \"%s\") failed: %s", hConHandle, mode, err); g_free(err); return NULL; } if (setvbuf(fp, NULL, _IONBF, 0) != 0) { gchar *err = g_win32_error_message(GetLastError()); g_warning("setvbuf(%p, NULL, _IONBF, 0) failed: %s", fp, err); g_free(err); fclose(fp); return NULL; } return fp; } static void debug_setup_console(void) { static const WORD MAX_CONSOLE_LINES = 500; CONSOLE_SCREEN_BUFFER_INFO coninfo; FILE *fp; /* allocate a console for this app */ AllocConsole(); /* set the screen buffer to be big enough to let us scroll text */ GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo); coninfo.dwSize.Y = MAX_CONSOLE_LINES; SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize); /* redirect unbuffered STDOUT to the console */ fp = open_std_handle(STD_OUTPUT_HANDLE, "w"); if (fp) *stdout = *fp; /* redirect unbuffered STDERR to the console */ fp = open_std_handle(STD_ERROR_HANDLE, "w"); if (fp) *stderr = *fp; /* redirect unbuffered STDIN to the console */ fp = open_std_handle(STD_INPUT_HANDLE, "r"); if (fp) *stdin = *fp; } void win32_init_debug_code(void) { if (app->debug_mode) { /* create a console window to get log messages on Windows, * especially useful when generating tags files */ debug_setup_console(); } } /* expands environment placeholders in @str. input and output is in UTF-8 */ gchar *win32_expand_environment_variables(const gchar *str) { wchar_t *cmdline = g_utf8_to_utf16(str, -1, NULL, NULL, NULL); wchar_t expCmdline[32768]; /* 32768 is the limit for ExpandEnvironmentStrings() */ gchar *expanded = NULL; if (cmdline && ExpandEnvironmentStringsW(cmdline, expCmdline, sizeof(expCmdline)) != 0) expanded = g_utf16_to_utf8(expCmdline, -1, NULL, NULL, NULL); g_free(cmdline); return expanded ? expanded : g_strdup(str); } /* From GDK (they got it from MS Knowledge Base article Q130698) */ static gboolean resolve_link(HWND hWnd, wchar_t *link, gchar **lpszPath) { WIN32_FILE_ATTRIBUTE_DATA wfad; HRESULT hres; IShellLinkW *pslW = NULL; IPersistFile *ppf = NULL; LPVOID pslWV = NULL; LPVOID ppfV = NULL; /* Check if the file is empty first because IShellLink::Resolve for some reason succeeds * with an empty file and returns an empty "link target". (#524151) */ if (!GetFileAttributesExW(link, GetFileExInfoStandard, &wfad) || (wfad.nFileSizeHigh == 0 && wfad.nFileSizeLow == 0)) { return FALSE; } /* Assume failure to start with: */ *lpszPath = 0; CoInitialize(NULL); hres = CoCreateInstance( &CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, &IID_IShellLinkW, &pslWV); if (SUCCEEDED(hres)) { /* The IShellLink interface supports the IPersistFile interface. * Get an interface pointer to it. */ pslW = (IShellLinkW*) pslWV; hres = pslW->lpVtbl->QueryInterface(pslW, &IID_IPersistFile, &ppfV); } if (SUCCEEDED(hres)) { /* Load the file. */ ppf = (IPersistFile*) ppfV; hres = ppf->lpVtbl->Load(ppf, link, STGM_READ); } if (SUCCEEDED(hres)) { /* Resolve the link by calling the Resolve() interface function. */ hres = pslW->lpVtbl->Resolve(pslW, hWnd, SLR_ANY_MATCH | SLR_NO_UI); } if (SUCCEEDED(hres)) { wchar_t wtarget[MAX_PATH]; hres = pslW->lpVtbl->GetPath(pslW, wtarget, MAX_PATH, NULL, 0); if (SUCCEEDED(hres)) *lpszPath = g_utf16_to_utf8(wtarget, -1, NULL, NULL, NULL); } if (ppf) ppf->lpVtbl->Release(ppf); if (pslW) pslW->lpVtbl->Release(pslW); return SUCCEEDED(hres); } /* Checks whether file_name is a Windows shortcut. file_name is expected in UTF-8 encoding. * If file_name is a Windows shortcut, it returns the target in UTF-8 encoding. * If it is not a shortcut, it returns a newly allocated copy of file_name. */ gchar *win32_get_shortcut_target(const gchar *file_name) { gchar *path = NULL; wchar_t *wfilename = g_utf8_to_utf16(file_name, -1, NULL, NULL, NULL); HWND hWnd = NULL; if (main_widgets.window != NULL) { GdkWindow *window = gtk_widget_get_window(main_widgets.window); if (window != NULL) hWnd = GDK_WINDOW_HWND(window); } resolve_link(hWnd, wfilename, &path); g_free(wfilename); if (path == NULL) return g_strdup(file_name); else return path; } void win32_set_working_directory(const gchar *dir) { SetCurrentDirectory(dir); } gchar *win32_get_installation_dir(void) { return g_win32_get_package_installation_directory_of_module(NULL); } gchar *win32_get_user_config_dir(void) { HRESULT hr; wchar_t path[MAX_PATH]; hr = SHGetFolderPathAndSubDirW(NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE, NULL, SHGFP_TYPE_CURRENT, L"geany", path); if (SUCCEEDED(hr)) { // GLib always uses UTF-8 for filename encoding on Windows int u8_size = WideCharToMultiByte(CP_UTF8, 0, path, -1, NULL, 0, NULL, NULL); if (u8_size > 0) { gchar *u8_path = g_malloc0(u8_size + 1); if (u8_path != NULL && WideCharToMultiByte(CP_UTF8, 0, path, -1, u8_path, u8_size, NULL, NULL)) { return u8_path; } } } // glib fallback g_warning("Failed to retrieve Windows config dir, falling back to default"); return g_build_filename(g_get_user_config_dir(), "geany", NULL); } #endif geany-2.0/src/gb.c0000644000175000017500000003304414514252267010736 00000000000000/* * gb.c - this file is part of Geany, a fast and lightweight IDE * * Copyright 2005 The Geany contributors * * This program 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; either version 2 of the License, or * (at your option) any later version. * * This program 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /* * A small Pong-like. */ #include "utils.h" #include #define AREA_SIZE 300 #define BALL_SIZE 4 #define BORDER_THIKNESS 4 #define HANDLE_THIKNESS 4 #define HANDLE_SHRINK 3 #define GEANY_TYPE_PONG (geany_pong_get_type()) #define GEANY_PONG(o) (G_TYPE_CHECK_INSTANCE_CAST((o), GEANY_TYPE_PONG, GeanyPong)) #define GEANY_IS_PONG(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), GEANY_TYPE_PONG)) typedef struct _GeanyPong GeanyPong; typedef struct _GeanyPongClass GeanyPongClass; struct _GeanyPong { GtkDialog parent; /* no need for private data as the whole thing is private */ GtkWidget *score_label; GtkWidget *area; gint area_height; gint area_width; guint ball_speed; gdouble ball_pos[2]; gdouble ball_vec[2]; gint handle_width; gint handle_pos; guint score; guint source_id; }; struct _GeanyPongClass { GtkDialogClass parent_class; }; static void geany_pong_finalize(GObject *obj); static void geany_pong_response(GtkDialog *self, gint response); static GType geany_pong_get_type(void) G_GNUC_CONST; G_DEFINE_TYPE(GeanyPong, geany_pong, GTK_TYPE_DIALOG) static void geany_pong_set_cairo_source_color(cairo_t *cr, GdkRGBA *c, gdouble a) { cairo_set_source_rgba(cr, c->red, c->green, c->blue, MIN(c->alpha, a)); } static gboolean geany_pong_area_draw(GtkWidget *area, cairo_t *cr, GeanyPong *self) { /* we use the window style context because the area one has a transparent * background and we want something to paint for the overlay */ GtkStyleContext *ctx = gtk_widget_get_style_context(GTK_WIDGET(self)); GtkStateFlags state = gtk_style_context_get_state(ctx); GdkRGBA fg, bg; gtk_style_context_get_color(ctx, state, &fg); gtk_style_context_get_background_color(ctx, state, &bg); self->area_width = gtk_widget_get_allocated_width(area); self->area_height = gtk_widget_get_allocated_height(area); cairo_set_line_width(cr, BORDER_THIKNESS); /* draw the border */ cairo_rectangle(cr, BORDER_THIKNESS/2, BORDER_THIKNESS/2, self->area_width - BORDER_THIKNESS, self->area_height /* we don't wanna see the bottom */); geany_pong_set_cairo_source_color(cr, &fg, 1.0); cairo_stroke(cr); /* draw the handle */ cairo_rectangle(cr, self->handle_pos - self->handle_width/2, self->area_height - HANDLE_THIKNESS, self->handle_width, HANDLE_THIKNESS); cairo_fill(cr); /* draw the ball */ cairo_arc(cr, self->ball_pos[0], self->ball_pos[1], BALL_SIZE, 0, 2*G_PI); cairo_fill(cr); /* if not running, add an info */ if (! self->source_id || self->handle_width < 1) { PangoLayout *layout; gint pw, ph; gdouble scale; PangoFontDescription *font = NULL; geany_pong_set_cairo_source_color(cr, &bg, 0.8); cairo_rectangle(cr, 0, 0, self->area_width, self->area_height); cairo_paint(cr); geany_pong_set_cairo_source_color(cr, &fg, 1.0); layout = pango_cairo_create_layout(cr); gtk_style_context_get(ctx, state, GTK_STYLE_PROPERTY_FONT, &font, NULL); if (font) { pango_layout_set_font_description(layout, font); pango_font_description_free(font); } if (! self->handle_width) pango_layout_set_markup(layout, "You won!\nOK, go back to work now.", -1); else pango_layout_set_text(layout, "Click to Play", -1); pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER); pango_layout_get_pixel_size(layout, &pw, &ph); scale = MIN(0.9 * self->area_width / pw, 0.9 * self->area_height / ph); cairo_move_to(cr, (self->area_width - pw * scale) / 2, (self->area_height - ph * scale) / 2); cairo_scale(cr, scale, scale); pango_cairo_show_layout(cr, layout); g_object_unref(layout); } return TRUE; } static void geany_pong_reset_ball(GeanyPong *self) { self->ball_speed = 5; self->ball_pos[0] = self->area_width / 2; self->ball_pos[1] = self->area_height / 2; self->ball_vec[0] = g_random_double_range(.2, .8); self->ball_vec[1] = 1.0 - self->ball_vec[0]; if (g_random_boolean()) self->ball_vec[0] *= -1; } static void geany_pong_update_score(GeanyPong *self) { gchar buf[16]; g_snprintf(buf, sizeof buf, "%u", self->score); gtk_label_set_text(GTK_LABEL(self->score_label), buf); } static gboolean geany_pong_area_timeout(gpointer data) { GeanyPong *self = data; const gdouble x = BORDER_THIKNESS + BALL_SIZE/2; const gdouble y = BORDER_THIKNESS + BALL_SIZE/2; const gdouble w = self->area_width - BORDER_THIKNESS - BALL_SIZE/2; const gdouble h = self->area_height - HANDLE_THIKNESS - BALL_SIZE/2; const gdouble old_ball_pos[2] = { self->ball_pos[0], self->ball_pos[1] }; const gdouble step[2] = { self->ball_speed * self->ball_vec[0], self->ball_speed * self->ball_vec[1] }; /* left & right */ if (self->ball_pos[0] + step[0] >= w || self->ball_pos[0] + step[0] <= x) self->ball_vec[0] = -self->ball_vec[0]; /* top */ if (self->ball_pos[1] + step[1] <= y) self->ball_vec[1] = -self->ball_vec[1]; /* bottom */ if (self->ball_pos[1] + step[1] >= h) { if (self->ball_pos[0] + step[0] >= self->handle_pos - self->handle_width/2 && self->ball_pos[0] + step[0] <= self->handle_pos + self->handle_width/2 && /* only bounce *above* the handle, not below */ self->ball_pos[1] <= h) { self->score += self->ball_speed * 2; geany_pong_update_score(self); self->ball_vec[1] = -self->ball_vec[1]; self->ball_speed++; self->handle_width -= HANDLE_SHRINK; /* we don't allow a handle smaller than a shrink step */ if (self->handle_width < HANDLE_SHRINK) { self->handle_width = 0; self->source_id = 0; } } /* let the ball fall completely off before losing */ else if (self->ball_pos[1] + step[1] >= self->area_height + BALL_SIZE) { /* lost! */ self->source_id = 0; geany_pong_reset_ball(self); } } if (self->source_id) { self->ball_pos[0] += self->ball_speed * self->ball_vec[0]; self->ball_pos[1] += self->ball_speed * self->ball_vec[1]; } if (! self->source_id) { /* we will draw a text all over, just invalidate everything */ gtk_widget_queue_draw(self->area); } else { /* compute the rough bounding box to redraw the ball */ const gint bb[4] = { (gint) MIN(self->ball_pos[0], old_ball_pos[0]) - BALL_SIZE - 1, (gint) MIN(self->ball_pos[1], old_ball_pos[1]) - BALL_SIZE - 1, (gint) MAX(self->ball_pos[0], old_ball_pos[0]) + BALL_SIZE + 1, (gint) MAX(self->ball_pos[1], old_ball_pos[1]) + BALL_SIZE + 1 }; gtk_widget_queue_draw_area(self->area, bb[0], bb[1], bb[2] - bb[0], bb[3] - bb[1]); /* always redraw the handle in case it has moved */ gtk_widget_queue_draw_area(self->area, BORDER_THIKNESS, self->area_height - HANDLE_THIKNESS, self->area_width - BORDER_THIKNESS*2, HANDLE_THIKNESS); } return self->source_id != 0; } static gboolean geany_pong_area_button_press(GtkWidget *area, GdkEventButton *event, GeanyPong *self) { if (event->type == GDK_BUTTON_PRESS && self->handle_width > 0) { if (! self->source_id) self->source_id = g_timeout_add(1000/60, geany_pong_area_timeout, self); else { g_source_remove(self->source_id); self->source_id = 0; } gtk_widget_queue_draw(area); return TRUE; } return FALSE; } static gboolean geany_pong_area_motion_notify(GtkWidget *area, GdkEventMotion *event, GeanyPong *self) { self->handle_pos = (gint) event->x; /* clamp so the handle is always fully in */ if (self->handle_pos < self->handle_width/2 + BORDER_THIKNESS) self->handle_pos = self->handle_width/2 + BORDER_THIKNESS; else if (self->handle_pos > self->area_width - self->handle_width/2 - BORDER_THIKNESS) self->handle_pos = self->area_width - self->handle_width/2 - BORDER_THIKNESS; return TRUE; } static void geany_pong_class_init(GeanyPongClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS(klass); GtkDialogClass *dialog_class = GTK_DIALOG_CLASS(klass); object_class->finalize = geany_pong_finalize; dialog_class->response = geany_pong_response; } static void geany_pong_init(GeanyPong *self) { GtkWidget *vbox; GtkWidget *hbox; GtkWidget *label; self->score = 0; self->source_id = 0; self->area_height = AREA_SIZE; self->area_width = AREA_SIZE; self->handle_width = self->area_width / 2; self->handle_pos = self->area_width / 2; geany_pong_reset_ball(self); gtk_window_set_title(GTK_WINDOW(self), "Happy Easter!"); gtk_window_set_position(GTK_WINDOW(self), GTK_WIN_POS_CENTER_ON_PARENT); gtk_window_set_destroy_with_parent(GTK_WINDOW(self), TRUE); gtk_window_set_modal(GTK_WINDOW(self), TRUE); gtk_window_set_skip_pager_hint(GTK_WINDOW(self), TRUE); gtk_window_set_resizable(GTK_WINDOW(self), FALSE); vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); gtk_container_set_border_width(GTK_CONTAINER(vbox), 5); gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(self))), vbox, TRUE, TRUE, 0); hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); label = gtk_label_new("Score:"); gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5); gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0); self->score_label = gtk_label_new("0"); gtk_box_pack_start(GTK_BOX(hbox), self->score_label, FALSE, FALSE, 0); self->area = gtk_drawing_area_new(); gtk_widget_add_events(self->area, GDK_BUTTON_PRESS_MASK | GDK_POINTER_MOTION_MASK); g_signal_connect(self->area, "draw", G_CALLBACK(geany_pong_area_draw), self); g_signal_connect(self->area, "button-press-event", G_CALLBACK(geany_pong_area_button_press), self); g_signal_connect(self->area, "motion-notify-event", G_CALLBACK(geany_pong_area_motion_notify), self); gtk_widget_set_size_request(self->area, AREA_SIZE, AREA_SIZE); gtk_box_pack_start(GTK_BOX(vbox), self->area, TRUE, TRUE, 0); gtk_dialog_add_buttons(GTK_DIALOG(self), GTK_STOCK_HELP, GTK_RESPONSE_HELP, GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, NULL); gtk_dialog_set_default_response(GTK_DIALOG(self), GTK_RESPONSE_HELP); gtk_widget_grab_focus(gtk_dialog_get_widget_for_response(GTK_DIALOG(self), GTK_RESPONSE_HELP)); gtk_widget_show_all(vbox); } static void geany_pong_finalize(GObject *obj) { GeanyPong *self = GEANY_PONG(obj); if (self->source_id) g_source_remove(self->source_id); G_OBJECT_CLASS(geany_pong_parent_class)->finalize(obj); } static void geany_pong_help(GeanyPong *self) { GtkWidget *dialog; GtkWidget *vbox; GtkWidget *scrolledwindow; GtkWidget *textview; GtkTextBuffer *buffer; dialog = gtk_dialog_new_with_buttons("Help", GTK_WINDOW(self), GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL, GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, NULL); gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_CLOSE); gtk_container_set_border_width(GTK_CONTAINER(dialog), 1); gtk_window_set_type_hint(GTK_WINDOW(dialog), GDK_WINDOW_TYPE_HINT_DIALOG); vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); scrolledwindow = gtk_scrolled_window_new(NULL, NULL); gtk_box_pack_start(GTK_BOX(vbox), scrolledwindow, TRUE, TRUE, 0); gtk_container_set_border_width(GTK_CONTAINER(scrolledwindow), 5); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwindow), GTK_POLICY_NEVER, GTK_POLICY_NEVER); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolledwindow), GTK_SHADOW_IN); textview = gtk_text_view_new(); gtk_container_add(GTK_CONTAINER(scrolledwindow), textview); gtk_widget_set_size_request(textview, 450, -1); gtk_text_view_set_editable(GTK_TEXT_VIEW(textview), FALSE); gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(textview), GTK_WRAP_WORD); gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(textview), FALSE); gtk_text_view_set_left_margin(GTK_TEXT_VIEW(textview), 2); gtk_text_view_set_right_margin(GTK_TEXT_VIEW(textview), 2); buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview)); gtk_text_buffer_set_text(buffer, "A small Pong-like\n" "\n" "Click to start, and then bounce the ball off the walls without it " "falling down the bottom edge. You control the bottom handle with " "the mouse, but beware! the ball goes faster and faster and the " "handle grows smaller and smaller!", -1); gtk_widget_show_all(dialog); gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); } static void geany_pong_response(GtkDialog *self, gint response) { g_return_if_fail(GEANY_IS_PONG(self)); switch (response) { case GTK_RESPONSE_HELP: geany_pong_help(GEANY_PONG(self)); break; default: gtk_widget_destroy(GTK_WIDGET(self)); } } static GtkWidget *geany_pong_new(GtkWindow *parent) { return g_object_new(GEANY_TYPE_PONG, "transient-for", parent, NULL); } static gboolean gb_on_key_pressed(GtkWidget *widget, GdkEventKey *event, gpointer user_data) { static gchar text[] = "geany"; if (event->keyval < 0x80) { memmove (text, &text[1], G_N_ELEMENTS(text) - 1); text[G_N_ELEMENTS(text) - 2] = (gchar) event->keyval; if (utils_str_equal(text, "geany")) { GtkWidget *pong = geany_pong_new(GTK_WINDOW(widget)); gtk_widget_show(pong); return TRUE; } } return FALSE; } geany-2.0/src/stash.h0000644000175000017500000000775514514252267011507 00000000000000/* * stash.h - this file is part of Geany, a fast and lightweight IDE * * Copyright 2008 The Geany contributors * * This program 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; either version 2 of the License, or * (at your option) any later version. * * This program 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef GEANY_STASH_H #define GEANY_STASH_H 1 #include "gtkcompat.h" G_BEGIN_DECLS /** Opaque type for a group of settings. */ typedef struct StashGroup StashGroup; /** Can be @c GtkWidget* or @c gchar* depending on whether the @a owner argument is used for * stash_group_display() and stash_group_update(). */ typedef gconstpointer StashWidgetID; GType stash_group_get_type(void); StashGroup *stash_group_new(const gchar *name); void stash_group_add_boolean(StashGroup *group, gboolean *setting, const gchar *key_name, gboolean default_value); void stash_group_add_double(StashGroup *group, gdouble *setting, const gchar *key_name, gdouble default_value); void stash_group_add_integer(StashGroup *group, gint *setting, const gchar *key_name, gint default_value); void stash_group_add_string(StashGroup *group, gchar **setting, const gchar *key_name, const gchar *default_value); void stash_group_add_string_vector(StashGroup *group, gchar ***setting, const gchar *key_name, const gchar **default_value); void stash_group_load_from_key_file(StashGroup *group, GKeyFile *keyfile); void stash_group_save_to_key_file(StashGroup *group, GKeyFile *keyfile); void stash_group_free(StashGroup *group); gboolean stash_group_load_from_file(StashGroup *group, const gchar *filename); gint stash_group_save_to_file(StashGroup *group, const gchar *filename, GKeyFileFlags flags); /* *** GTK-related functions *** */ void stash_group_add_toggle_button(StashGroup *group, gboolean *setting, const gchar *key_name, gboolean default_value, StashWidgetID widget_id); void stash_group_add_radio_buttons(StashGroup *group, gint *setting, const gchar *key_name, gint default_value, StashWidgetID widget_id, gint enum_id, ...) G_GNUC_NULL_TERMINATED; void stash_group_add_spin_button_integer(StashGroup *group, gint *setting, const gchar *key_name, gint default_value, StashWidgetID widget_id); void stash_group_add_combo_box(StashGroup *group, gint *setting, const gchar *key_name, gint default_value, StashWidgetID widget_id); void stash_group_add_combo_box_entry(StashGroup *group, gchar **setting, const gchar *key_name, const gchar *default_value, StashWidgetID widget_id); void stash_group_add_entry(StashGroup *group, gchar **setting, const gchar *key_name, const gchar *default_value, StashWidgetID widget_id); void stash_group_add_widget_property(StashGroup *group, gpointer setting, const gchar *key_name, gpointer default_value, StashWidgetID widget_id, const gchar *property_name, GType type); void stash_group_display(StashGroup *group, GtkWidget *owner); void stash_group_update(StashGroup *group, GtkWidget *owner); void stash_group_free_settings(StashGroup *group); #ifdef GEANY_PRIVATE void stash_group_set_various(StashGroup *group, gboolean various, const gchar *prefix); void stash_group_set_use_defaults(StashGroup *group, gboolean use_defaults); /* *** GTK-related functions *** */ void stash_tree_setup(GPtrArray *group_array, GtkTreeView *tree); void stash_tree_display(GtkTreeView *tree); void stash_tree_update(GtkTreeView *tree); #endif /* GEANY_PRIVATE */ G_END_DECLS #endif /* GEANY_STASH_H */ geany-2.0/src/document.h0000644000175000017500000002603314514252267012171 00000000000000/* * document.h - this file is part of Geany, a fast and lightweight IDE * * Copyright 2005 The Geany contributors * * This program 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; either version 2 of the License, or * (at your option) any later version. * * This program 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /** * @file document.h * Document related actions: new, save, open, etc. **/ /* Also Scintilla search actions - but these should probably be moved to search.c. */ #ifndef GEANY_DOCUMENT_H #define GEANY_DOCUMENT_H 1 #include "editor.h" #include "filetypes.h" #include "geany.h" #include "search.h" #include "gtkcompat.h" /* Needed by ScintillaWidget.h */ #include "Scintilla.h" /* Needed by ScintillaWidget.h */ #include "ScintillaWidget.h" /* For ScintillaObject */ #include G_BEGIN_DECLS /** File Prefs. */ typedef struct GeanyFilePrefs { gint default_new_encoding; gint default_open_encoding; gboolean final_new_line; gboolean strip_trailing_spaces; gboolean replace_tabs; gboolean tab_order_ltr; gboolean tab_order_beside; gboolean show_tab_cross; guint mru_length; gint default_eol_character; gint disk_check_timeout; gboolean cmdline_new_files; /* New file if command-line filename doesn't exist */ gboolean use_safe_file_saving; gboolean ensure_convert_new_lines; gboolean gio_unsafe_save_backup; gboolean use_gio_unsafe_file_saving; /* whether to use GIO as the unsafe backend */ gchar *extract_filetype_regex; /* regex to extract filetype on opening */ gboolean tab_close_switch_to_mru; gboolean keep_edit_history_on_reload; /* Keep undo stack upon, and allow undoing of, document reloading. */ gboolean show_keep_edit_history_on_reload_msg; /* whether to show the message introducing the above feature */ gboolean reload_clean_doc_on_file_change; gboolean save_config_on_file_change; } GeanyFilePrefs; #define GEANY_TYPE_DOCUMENT (document_get_type()) GType document_get_type (void); /** * Structure for representing an open tab with all its properties. **/ typedef struct GeanyDocument { /** Flag used to check if this document is valid when iterating @ref GeanyData::documents_array. */ gboolean is_valid; gint index; /**< Index in the documents array. */ /** Whether this document supports source code symbols(tags) to show in the sidebar. */ gboolean has_tags; /** The UTF-8 encoded file name. * Be careful; glibc and GLib file functions expect the locale representation of the * file name which can be different from this. * For conversion into locale encoding, you can use @ref utils_get_locale_from_utf8(). * @see real_path. */ gchar *file_name; /** The encoding of the document, must be a valid string representation of an encoding, can * be retrieved with @ref encodings_get_charset_from_index. */ gchar *encoding; /** Internally used flag to indicate whether the file of this document has a byte-order-mark. */ gboolean has_bom; GeanyEditor *editor; /**< The editor associated with the document. */ /** The filetype for this document, it's only a reference to one of the elements of the global * filetypes array. */ GeanyFiletype *file_type; /** TMSourceFile object for this document, or @c NULL. */ TMSourceFile *tm_file; /** Whether this document is read-only. */ gboolean readonly; /** Whether this document has been changed since it was last saved. */ gboolean changed; /** The link-dereferenced, locale-encoded file name. * If non-NULL, this indicates the file once existed on disk (not just as an * unsaved document with a filename set). * * @note This is only assigned after a successful save or open - it should * not be set elsewhere. * @see file_name. */ gchar *real_path; /** A pseudo-unique ID for this document. * @c 0 is reserved as an unused value. * @see document_find_by_id(). */ guint id; struct GeanyDocumentPrivate *priv; /* should be last, append fields before this item */ } GeanyDocument; /** Wraps @ref GeanyData::documents_array so it can be used with C array syntax. * @warning Always check the returned document is valid (@c doc->is_valid). * * Example: @code GeanyDocument *doc = documents[i]; @endcode * @see documents_array(). */ #define documents ((GeanyDocument **)GEANY(documents_array)->pdata) /** Iterates all valid document indexes. * Use like a @c for statement. * @param i @c guint index for @ref GeanyData::documents_array. * * Example: * @code * guint i; * foreach_document(i) * { * GeanyDocument *doc = documents[i]; * g_assert(doc->is_valid); * } * @endcode */ #define foreach_document(i) \ for (i = 0; i < GEANY(documents_array)->len; i++)\ if (!documents[i]->is_valid)\ {}\ else /* prevent outside 'else' matching our macro 'if' */ /** Null-safe way to check @ref GeanyDocument::is_valid. * @note This should not be used to check the result of the main API functions, * these only need a NULL-pointer check - @c document_get_current() != @c NULL. */ #define DOC_VALID(doc_ptr) \ ((doc_ptr) != NULL && (doc_ptr)->is_valid) /** * Returns the filename of the document passed or @c GEANY_STRING_UNTITLED * (e.g. _("untitled")) if the document's filename was not yet set. * This macro never returns @c NULL. **/ #define DOC_FILENAME(doc) \ (G_LIKELY((doc)->file_name != NULL) ? ((doc)->file_name) : GEANY_STRING_UNTITLED) GeanyDocument* document_new_file(const gchar *filename, GeanyFiletype *ft, const gchar *text); GeanyDocument *document_get_current(void); GeanyDocument *document_get_from_notebook_child(GtkWidget *page); GeanyDocument* document_get_from_page(guint page_num); GeanyDocument* document_find_by_filename(const gchar *utf8_filename); GeanyDocument* document_find_by_real_path(const gchar *realname); gboolean document_save_file(GeanyDocument *doc, gboolean force); GeanyDocument* document_open_file(const gchar *locale_filename, gboolean readonly, GeanyFiletype *ft, const gchar *forced_enc); void document_open_files(const GSList *filenames, gboolean readonly, GeanyFiletype *ft, const gchar *forced_enc); gboolean document_remove_page(guint page_num); gboolean document_reload_force(GeanyDocument *doc, const gchar *forced_enc); void document_set_encoding(GeanyDocument *doc, const gchar *new_encoding); void document_set_text_changed(GeanyDocument *doc, gboolean changed); void document_set_filetype(GeanyDocument *doc, GeanyFiletype *type); gboolean document_close(GeanyDocument *doc); GeanyDocument *document_index(gint idx); gboolean document_save_file_as(GeanyDocument *doc, const gchar *utf8_fname); void document_rename_file(GeanyDocument *doc, const gchar *new_filename); const GdkColor *document_get_status_color(GeanyDocument *doc); gchar *document_get_basename_for_display(GeanyDocument *doc, gint length); gint document_get_notebook_page(GeanyDocument *doc); gint document_compare_by_display_name(gconstpointer a, gconstpointer b); gint document_compare_by_tab_order(gconstpointer a, gconstpointer b); gint document_compare_by_tab_order_reverse(gconstpointer a, gconstpointer b); GeanyDocument *document_find_by_id(guint id); #ifdef GEANY_PRIVATE #if defined(G_OS_WIN32) # define GEANY_DEFAULT_EOL_CHARACTER SC_EOL_CRLF #else # define GEANY_DEFAULT_EOL_CHARACTER SC_EOL_LF #endif extern GeanyFilePrefs file_prefs; extern GPtrArray *documents_array; /* These functions will replace the older functions. For now they have a documents_ prefix. */ GeanyDocument* document_new_file_if_non_open(void); gboolean document_reload_prompt(GeanyDocument *doc, const gchar *forced_enc); void document_reload_config(GeanyDocument *doc); GeanyDocument *document_find_by_sci(ScintillaObject *sci); void document_show_tab(GeanyDocument *doc); void document_show_tab_idle(GeanyDocument *doc); void document_init_doclist(void); void document_finalize(void); void document_try_focus(GeanyDocument *doc, GtkWidget *source_widget); gboolean document_account_for_unsaved(void); gboolean document_close_all(void); GeanyDocument *document_open_file_full(GeanyDocument *doc, const gchar *filename, gint pos, gboolean readonly, GeanyFiletype *ft, const gchar *forced_enc); void document_open_file_list(const gchar *data, gsize length); gboolean document_search_bar_find(GeanyDocument *doc, const gchar *text, gboolean inc, gboolean backwards); gint document_find_text(GeanyDocument *doc, const gchar *text, const gchar *original_text, GeanyFindFlags flags, gboolean search_backwards, GeanyMatchInfo **match_, gboolean scroll, GtkWidget *parent); gint document_replace_text(GeanyDocument *doc, const gchar *find_text, const gchar *original_find_text, const gchar *replace_text, GeanyFindFlags flags, gboolean search_backwards); gint document_replace_all(GeanyDocument *doc, const gchar *find_text, const gchar *replace_text, const gchar *original_find_text, const gchar *original_replace_text, GeanyFindFlags flags); void document_replace_sel(GeanyDocument *doc, const gchar *find_text, const gchar *replace_text, const gchar *original_find_text, const gchar *original_replace_text, GeanyFindFlags flags); void document_update_tags(GeanyDocument *doc); void document_update_tag_list_in_idle(GeanyDocument *doc); void document_highlight_tags(GeanyDocument *doc); gboolean document_check_disk_status(GeanyDocument *doc, gboolean force); /* own Undo / Redo implementation to be able to undo / redo changes * to the encoding or the Unicode BOM (which are Scintilla independent). * All Scintilla events are stored in the undo / redo buffer and are passed through. */ gboolean document_can_undo(GeanyDocument *doc); gboolean document_can_redo(GeanyDocument *doc); void document_undo(GeanyDocument *doc); void document_redo(GeanyDocument *doc); void document_undo_add(GeanyDocument *doc, guint type, gpointer data); void document_update_tab_label(GeanyDocument *doc); const gchar *document_get_status_widget_class(GeanyDocument *doc); gboolean document_need_save_as(GeanyDocument *doc); gboolean document_detect_indent_type(GeanyDocument *doc, GeanyIndentType *type_); gboolean document_detect_indent_width(GeanyDocument *doc, gint *width_); void document_apply_indent_settings(GeanyDocument *doc); void document_grab_focus(GeanyDocument *doc); GeanyDocument *document_clone(GeanyDocument *old_doc); gpointer document_get_data(const GeanyDocument *doc, const gchar *key); void document_set_data(GeanyDocument *doc, const gchar *key, gpointer data); void document_set_data_full(GeanyDocument *doc, const gchar *key, gpointer data, GDestroyNotify free_func); #endif /* GEANY_PRIVATE */ G_END_DECLS #endif /* GEANY_DOCUMENT_H */ geany-2.0/src/filetypes.c0000644000175000017500000013256614514252267012363 00000000000000/* * filetypes.c - this file is part of Geany, a fast and lightweight IDE * * Copyright 2005 The Geany contributors * * This program 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; either version 2 of the License, or * (at your option) any later version. * * This program 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /** * @file filetypes.h * Filetype detection, file extensions and filetype menu items. */ /* Note: we use GeanyFiletypeID for some function arguments, but GeanyFiletype is better; we should * only use GeanyFiletype for API functions. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include "filetypes.h" #include "app.h" #include "callbacks.h" /* FIXME: for ignore_callback */ #include "document.h" #include "filetypesprivate.h" #include "geany.h" #include "geanyobject.h" #include "highlighting.h" #include "projectprivate.h" #include "sciwrappers.h" #include "support.h" #include "symbols.h" #include "tm_parser.h" #include "utils.h" #include "ui_utils.h" #include #include #include #define GEANY_FILETYPE_SEARCH_LINES 2 /* lines of file to search for filetype */ GPtrArray *filetypes_array = NULL; static GHashTable *filetypes_hash = NULL; /* Hash of filetype pointers based on name keys */ GSList *filetypes_by_title = NULL; static void create_radio_menu_item(GtkWidget *menu, GeanyFiletype *ftype); static gchar *filetypes_get_conf_extension(const GeanyFiletype *ft); static void read_filetype_config(void); static void create_set_filetype_menu(gboolean config); static gchar *filetypes_get_filename(GeanyFiletype *ft, gboolean user); enum TitleType { TITLE_NONE, TITLE_SOURCE_FILE, TITLE_FILE, TITLE_SCRIPT, TITLE_DOCUMENT }; /* Save adding many translation strings if the filetype name doesn't need translating */ static gchar *filetype_make_title(const char *name, enum TitleType type) { g_return_val_if_fail(name != NULL, NULL); switch (type) { case TITLE_SOURCE_FILE: return g_strdup_printf(_("%s source file"), name); case TITLE_FILE: return g_strdup_printf(_("%s file"), name); case TITLE_SCRIPT: return g_strdup_printf(_("%s script"), name); case TITLE_DOCUMENT: return g_strdup_printf(_("%s document"), name); case TITLE_NONE: /* fall through */ default: return g_strdup(name); } } /* name argument (ie filetype name) must not be translated as it is used for * filetype lookup. Use filetypes_get_display_name() instead.*/ static void ft_init(GeanyFiletypeID ft_id, TMParserType lang, const char *name, const char *title_name, enum TitleType title_type, GeanyFiletypeGroupID group_id) { GeanyFiletype *ft = filetypes[ft_id]; ft->lang = lang; ft->name = g_strdup(name); ft->title = filetype_make_title((title_name != NULL) ? title_name : ft->name, title_type); ft->group = group_id; } /* Evil macro to save typing and make init_builtin_filetypes() more readable */ #define FT_INIT(ft_id, parser_id, name, title_name, title_type, group_id) \ ft_init(GEANY_FILETYPES_##ft_id, TM_PARSER_##parser_id, name, title_name, \ TITLE_##title_type, GEANY_FILETYPE_GROUP_##group_id) /* Note: remember to update HACKING if this function is renamed. */ static void init_builtin_filetypes(void) { /* Column legend: * [0] = Filetype constant (GEANY_FILETYPES_*) * [1] = CTags parser (TM_PARSER_*) * [2] = Non-translated filetype name (*not* label for display) * [3] = Translatable human filetype title prefix or NULL to use [2] * [4] = Title type (TITLE_*) constant (ex. TITLE_SOURCE_FILE is 'source file' suffix) * [5] = The filetype group constant (GEANY_FILETYPE_GROUP_*) * -------------------------------------------------------------------------------------------------------------------------- * [0] [1] [2] [3] [4] [5] */ FT_INIT( NONE, NONE, "None", _("None"), NONE, NONE ); FT_INIT( C, C, "C", NULL, SOURCE_FILE, COMPILED ); FT_INIT( CPP, CPP, "C++", NULL, SOURCE_FILE, COMPILED ); FT_INIT( OBJECTIVEC, OBJC, "Objective-C", NULL, SOURCE_FILE, COMPILED ); FT_INIT( CS, CSHARP, "C#", NULL, SOURCE_FILE, COMPILED ); FT_INIT( VALA, VALA, "Vala", NULL, SOURCE_FILE, COMPILED ); FT_INIT( D, D, "D", NULL, SOURCE_FILE, COMPILED ); FT_INIT( JAVA, JAVA, "Java", NULL, SOURCE_FILE, COMPILED ); FT_INIT( PASCAL, PASCAL, "Pascal", NULL, SOURCE_FILE, COMPILED ); FT_INIT( ASM, ASM, "ASM", "Assembler", SOURCE_FILE, COMPILED ); FT_INIT( BASIC, FREEBASIC, "FreeBasic", NULL, SOURCE_FILE, COMPILED ); FT_INIT( FORTRAN, FORTRAN, "Fortran", "Fortran (F90)", SOURCE_FILE, COMPILED ); FT_INIT( F77, FORTRAN, "F77", "Fortran (F77)", SOURCE_FILE, COMPILED ); FT_INIT( GLSL, C, "GLSL", NULL, SOURCE_FILE, COMPILED ); FT_INIT( CAML, NONE, "CAML", "(O)Caml", SOURCE_FILE, COMPILED ); FT_INIT( PERL, PERL, "Perl", NULL, SOURCE_FILE, SCRIPT ); FT_INIT( PHP, PHP, "PHP", NULL, SOURCE_FILE, SCRIPT ); FT_INIT( JS, JAVASCRIPT, "Javascript", NULL, SOURCE_FILE, SCRIPT ); FT_INIT( PYTHON, PYTHON, "Python", NULL, SOURCE_FILE, SCRIPT ); FT_INIT( RUBY, RUBY, "Ruby", NULL, SOURCE_FILE, SCRIPT ); FT_INIT( TCL, TCLOO, "Tcl", NULL, SOURCE_FILE, SCRIPT ); FT_INIT( LUA, LUA, "Lua", NULL, SOURCE_FILE, SCRIPT ); FT_INIT( GDSCRIPT, GDSCRIPT, "GDScript", NULL, SOURCE_FILE, SCRIPT ); FT_INIT( HASKELL, HASKELL, "Haskell", NULL, SOURCE_FILE, COMPILED ); FT_INIT( MARKDOWN, MARKDOWN, "Markdown", NULL, SOURCE_FILE, MARKUP ); FT_INIT( TXT2TAGS, TXT2TAGS, "Txt2tags", NULL, SOURCE_FILE, MARKUP ); FT_INIT( ABC, ABC, "Abc", NULL, FILE, MISC ); FT_INIT( SH, SH, "Sh", _("Shell"), SCRIPT, SCRIPT ); FT_INIT( MAKE, MAKEFILE, "Make", _("Makefile"), NONE, SCRIPT ); FT_INIT( XML, NONE, "XML", NULL, DOCUMENT, MARKUP ); FT_INIT( DOCBOOK, DOCBOOK, "Docbook", NULL, DOCUMENT, MARKUP ); FT_INIT( HTML, HTML, "HTML", NULL, DOCUMENT, MARKUP ); FT_INIT( CSS, CSS, "CSS", _("Cascading Stylesheet"), NONE, MARKUP ); /* not really markup but fit quite well to HTML */ FT_INIT( SQL, SQL, "SQL", NULL, FILE, MISC ); FT_INIT( COBOL, COBOL, "COBOL", NULL, SOURCE_FILE, COMPILED ); FT_INIT( LATEX, LATEX, "LaTeX", NULL, SOURCE_FILE, MARKUP ); FT_INIT( BIBTEX, BIBTEX, "BibTeX", NULL, SOURCE_FILE, MARKUP ); FT_INIT( VHDL, VHDL, "VHDL", NULL, SOURCE_FILE, COMPILED ); FT_INIT( VERILOG, VERILOG, "Verilog", NULL, SOURCE_FILE, COMPILED ); FT_INIT( DIFF, DIFF, "Diff", NULL, FILE, MISC ); FT_INIT( LISP, LISP, "Lisp", NULL, SOURCE_FILE, SCRIPT ); FT_INIT( ERLANG, ERLANG, "Erlang", NULL, SOURCE_FILE, COMPILED ); FT_INIT( CONF, CONF, "Conf", _("Config"), FILE, MISC ); FT_INIT( PO, NONE, "Po", _("Gettext translation"), FILE, MISC ); FT_INIT( HAXE, HAXE, "Haxe", NULL, SOURCE_FILE, COMPILED ); FT_INIT( AS, ACTIONSCRIPT, "ActionScript", NULL, SOURCE_FILE, SCRIPT ); FT_INIT( R, R, "R", NULL, SOURCE_FILE, SCRIPT ); FT_INIT( REST, REST, "reStructuredText", NULL, SOURCE_FILE, MARKUP ); FT_INIT( MATLAB, MATLAB, "Matlab/Octave", NULL, SOURCE_FILE, SCRIPT ); FT_INIT( YAML, NONE, "YAML", NULL, FILE, MISC ); FT_INIT( CMAKE, NONE, "CMake", NULL, SOURCE_FILE, SCRIPT ); FT_INIT( NSIS, NSIS, "NSIS", NULL, SOURCE_FILE, SCRIPT ); FT_INIT( ADA, ADA, "Ada", NULL, SOURCE_FILE, COMPILED ); FT_INIT( FORTH, NONE, "Forth", NULL, SOURCE_FILE, SCRIPT ); FT_INIT( ASCIIDOC, ASCIIDOC, "Asciidoc", NULL, SOURCE_FILE, MARKUP ); FT_INIT( ABAQUS, ABAQUS, "Abaqus", NULL, SOURCE_FILE, SCRIPT ); FT_INIT( BATCH, BATCH, "Batch", NULL, SCRIPT, SCRIPT ); FT_INIT( POWERSHELL, POWERSHELL, "PowerShell", NULL, SOURCE_FILE, SCRIPT ); FT_INIT( RUST, RUST, "Rust", NULL, SOURCE_FILE, COMPILED ); FT_INIT( COFFEESCRIPT, NONE, "CoffeeScript", NULL, SOURCE_FILE, SCRIPT ); FT_INIT( GO, GO, "Go", NULL, SOURCE_FILE, COMPILED ); FT_INIT( ZEPHIR, ZEPHIR, "Zephir", NULL, SOURCE_FILE, COMPILED ); FT_INIT( SMALLTALK, NONE, "Smalltalk", NULL, SOURCE_FILE, SCRIPT ); FT_INIT( JULIA, JULIA, "Julia", NULL, SOURCE_FILE, SCRIPT ); FT_INIT( AU3, AUTOIT, "AutoIt", NULL, SCRIPT, SCRIPT ); } /* initialize fields. */ static GeanyFiletype *filetype_new(void) { GeanyFiletype *ft = g_new0(GeanyFiletype, 1); ft->group = GEANY_FILETYPE_GROUP_NONE; ft->lang = TM_PARSER_NONE; /* assume no tagmanager parser */ /* pattern must not be null */ ft->pattern = g_new0(gchar*, 1); ft->indent_width = -1; ft->indent_type = -1; ft->priv = g_new0(GeanyFiletypePrivate, 1); ft->priv->project_list_entry = -1; /* no entry */ return ft; } static gint cmp_filetype(gconstpointer pft1, gconstpointer pft2, gpointer data) { gboolean by_name = GPOINTER_TO_INT(data); const GeanyFiletype *ft1 = pft1, *ft2 = pft2; if (G_UNLIKELY(ft1->id == GEANY_FILETYPES_NONE)) return -1; if (G_UNLIKELY(ft2->id == GEANY_FILETYPES_NONE)) return 1; return by_name ? utils_str_casecmp(ft1->name, ft2->name) : utils_str_casecmp(ft1->title, ft2->title); } /** Gets a list of filetype pointers sorted by name. * The list does not change on subsequent calls. * @return @elementtype{GeanyFiletype} @transfer{none} The list - do not free. * @see filetypes_by_title. */ GEANY_API_SYMBOL const GSList *filetypes_get_sorted_by_name(void) { static GSList *list = NULL; g_return_val_if_fail(filetypes_by_title, NULL); if (!list) { list = g_slist_copy(filetypes_by_title); list = g_slist_sort_with_data(list, cmp_filetype, GINT_TO_POINTER(TRUE)); } return list; } /* Add a filetype pointer to the lists of available filetypes, * and set the filetype::id field. */ static void filetype_add(GeanyFiletype *ft) { g_return_if_fail(ft); g_return_if_fail(ft->name); ft->id = filetypes_array->len; /* len will be the index for filetype_array */ g_ptr_array_add(filetypes_array, ft); g_hash_table_insert(filetypes_hash, ft->name, ft); /* list will be sorted later */ filetypes_by_title = g_slist_prepend(filetypes_by_title, ft); } static void add_custom_filetype(const gchar *filename) { gchar *fn = utils_strdupa(strstr(filename, ".") + 1); gchar *dot = g_strrstr(fn, ".conf"); GeanyFiletype *ft; g_return_if_fail(dot); *dot = 0x0; if (g_hash_table_lookup(filetypes_hash, fn)) return; ft = filetype_new(); ft->name = g_strdup(fn); ft->title = filetype_make_title(ft->name, TITLE_FILE); ft->priv->custom = TRUE; filetype_add(ft); geany_debug("Added filetype %s (%d).", ft->name, ft->id); } static void init_custom_filetypes(const gchar *path) { GDir *dir; const gchar *filename; g_return_if_fail(path); dir = g_dir_open(path, 0, NULL); if (dir == NULL) return; foreach_dir(filename, dir) { const gchar prefix[] = "filetypes."; if (g_str_has_prefix(filename, prefix) && g_str_has_suffix(filename + strlen(prefix), ".conf")) { add_custom_filetype(filename); } } g_dir_close(dir); } /* Create the filetypes array and fill it with the known filetypes. * Warning: GTK isn't necessarily initialized yet. */ void filetypes_init_types(void) { GeanyFiletypeID ft_id; gchar *f; g_return_if_fail(filetypes_array == NULL); g_return_if_fail(filetypes_hash == NULL); filetypes_array = g_ptr_array_sized_new(GEANY_MAX_BUILT_IN_FILETYPES); filetypes_hash = g_hash_table_new(g_str_hash, g_str_equal); /* Create built-in filetypes */ for (ft_id = 0; ft_id < GEANY_MAX_BUILT_IN_FILETYPES; ft_id++) { filetypes[ft_id] = filetype_new(); } init_builtin_filetypes(); /* Add built-in filetypes to the hash now the name fields are set */ for (ft_id = 0; ft_id < GEANY_MAX_BUILT_IN_FILETYPES; ft_id++) { filetype_add(filetypes[ft_id]); } f = g_build_filename(app->datadir, GEANY_FILEDEFS_SUBDIR, NULL); init_custom_filetypes(f); g_free(f); f = g_build_filename(app->configdir, GEANY_FILEDEFS_SUBDIR, NULL); init_custom_filetypes(f); g_free(f); /* sort last instead of on insertion to prevent exponential time */ filetypes_by_title = g_slist_sort_with_data(filetypes_by_title, cmp_filetype, GINT_TO_POINTER(FALSE)); read_filetype_config(); } static void on_document_save(G_GNUC_UNUSED GObject *object, GeanyDocument *doc) { gchar *f, *basename; g_return_if_fail(!EMPTY(doc->real_path)); f = g_build_filename(app->configdir, "filetype_extensions.conf", NULL); if (utils_str_equal(doc->real_path, f)) filetypes_reload_extensions(); g_free(f); basename = g_path_get_basename(doc->real_path); if (g_str_has_prefix(basename, "filetypes.")) { guint i; for (i = 0; i < filetypes_array->len; i++) { GeanyFiletype *ft = filetypes[i]; f = filetypes_get_filename(ft, TRUE); if (utils_str_equal(doc->real_path, f)) { guint j; /* Note: we don't reload other filetypes, even though the named styles may have changed. * The user can do this manually with 'Tools->Reload Configuration' */ filetypes_load_config(i, TRUE); foreach_document(j) document_reload_config(documents[j]); g_free(f); break; } g_free(f); } } g_free(basename); } static void setup_config_file_menus(void) { gchar *f; f = g_build_filename(app->configdir, "filetype_extensions.conf", NULL); ui_add_config_file_menu_item(f, NULL, NULL); SETPTR(f, g_build_filename(app->configdir, GEANY_FILEDEFS_SUBDIR, "filetypes.common", NULL)); ui_add_config_file_menu_item(f, NULL, NULL); g_free(f); create_set_filetype_menu(TRUE); g_signal_connect(geany_object, "document-save", G_CALLBACK(on_document_save), NULL); } static GtkWidget *create_sub_menu(GtkWidget *parent, const gchar *title) { GtkWidget *menu, *item; menu = gtk_menu_new(); item = gtk_menu_item_new_with_mnemonic((title)); gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), menu); gtk_container_add(GTK_CONTAINER(parent), item); gtk_widget_show(item); return menu; } static void create_set_filetype_menu(gboolean config) { GtkWidget *group_menus[GEANY_FILETYPE_GROUP_COUNT] = {NULL}; GSList *node; GtkWidget *menu; menu = config ? ui_widgets.config_files_filetype_menu : ui_lookup_widget(main_widgets.window, "set_filetype1_menu"); group_menus[GEANY_FILETYPE_GROUP_COMPILED] = create_sub_menu(menu, _("_Programming Languages")); group_menus[GEANY_FILETYPE_GROUP_SCRIPT] = create_sub_menu(menu, _("_Scripting Languages")); group_menus[GEANY_FILETYPE_GROUP_MARKUP] = create_sub_menu(menu, _("_Markup Languages")); group_menus[GEANY_FILETYPE_GROUP_MISC] = create_sub_menu(menu, _("M_iscellaneous")); /* Append all filetypes to the menu */ foreach_slist(node, filetypes_by_title) { GeanyFiletype *ft = node->data; GtkWidget *parent = (ft->group != GEANY_FILETYPE_GROUP_NONE) ? group_menus[ft->group] : menu; /* we already have filetypes.common config entry */ if (config && ft->id == GEANY_FILETYPES_NONE) continue; if (config) { gchar *filename = filetypes_get_filename(ft, TRUE); ui_add_config_file_menu_item(filename, NULL, GTK_CONTAINER(parent)); g_free(filename); } else create_radio_menu_item(parent, ft); } } void filetypes_init(void) { filetypes_init_types(); create_set_filetype_menu(FALSE); setup_config_file_menus(); } static guint match_basename(const GeanyFiletype *ft, const gchar *base_filename) { if (G_UNLIKELY(ft->id == GEANY_FILETYPES_NONE)) return 0; for (guint j = 0; ft->pattern[j] != NULL; j++) { gchar *pat = ft->pattern[j]; if (g_pattern_match_simple(pat, base_filename)) { return strlen(pat); } } return 0; } static GeanyFiletype *detect_filetype_conf_file(const gchar *utf8_filename) { gchar *lfn = NULL; gchar *path; gboolean found = FALSE; #ifdef G_OS_WIN32 /* use lower case basename */ lfn = g_utf8_strdown(utf8_filename, -1); #else lfn = g_strdup(utf8_filename); #endif SETPTR(lfn, utils_get_locale_from_utf8(lfn)); path = g_build_filename(app->configdir, GEANY_FILEDEFS_SUBDIR, "filetypes.", NULL); if (g_str_has_prefix(lfn, path)) found = TRUE; SETPTR(path, g_build_filename(app->datadir, GEANY_FILEDEFS_SUBDIR, "filetypes.", NULL)); if (g_str_has_prefix(lfn, path)) found = TRUE; g_free(path); g_free(lfn); return found ? filetypes[GEANY_FILETYPES_CONF] : NULL; } /* Detect filetype only based on the filename extension. * utf8_filename can include the full path. * Returns: non-NULL */ GeanyFiletype *filetypes_detect_from_extension(const gchar *utf8_filename) { gchar *base_filename; GeanyFiletype *ft; guint plen = 0; ft = detect_filetype_conf_file(utf8_filename); if (ft) return ft; /* to match against the basename of the file (because of Makefile*) */ base_filename = g_path_get_basename(utf8_filename); #ifdef G_OS_WIN32 /* use lower case basename */ SETPTR(base_filename, g_utf8_strdown(base_filename, -1)); #endif for (guint i = 0; i < filetypes_array->len; i++) { guint mlen = match_basename(filetypes[i], base_filename); if (mlen > plen) { // longest pattern match wins plen = mlen; ft = filetypes[i]; } else if (mlen == plen && ft && !ft->priv->user_extensions && filetypes[i]->priv->user_extensions) { // user config overrides system if pattern len same ft = filetypes[i]; } } if (ft == NULL) ft = filetypes[GEANY_FILETYPES_NONE]; g_free(base_filename); return ft; } /* This detects the filetype of the file pointed by 'utf8_filename' and a list of filetype id's, * terminated by -1. * The detected filetype of the file is checked against every id in the passed list and if * there is a match, TRUE is returned. */ static gboolean shebang_find_and_match_filetype(const gchar *utf8_filename, gint first, ...) { GeanyFiletype *ft = NULL; gint test; gboolean result = FALSE; va_list args; ft = filetypes_detect_from_extension(utf8_filename); if (ft == NULL || ft->id >= filetypes_array->len) return FALSE; va_start(args, first); test = first; while (1) { if (test == -1) break; if (ft->id == (guint) test) { result = TRUE; break; } test = va_arg(args, gint); } va_end(args); return result; } static GeanyFiletype *find_shebang(const gchar *utf8_filename, const gchar *line) { GeanyFiletype *ft = NULL; if (strlen(line) > 2 && line[0] == '#' && line[1] == '!') { static const struct { const gchar *name; GeanyFiletypeID filetype; } intepreter_map[] = { { "sh", GEANY_FILETYPES_SH }, { "bash", GEANY_FILETYPES_SH }, { "dash", GEANY_FILETYPES_SH }, { "perl", GEANY_FILETYPES_PERL }, { "python", GEANY_FILETYPES_PYTHON }, { "php", GEANY_FILETYPES_PHP }, { "ruby", GEANY_FILETYPES_RUBY }, { "tcl", GEANY_FILETYPES_TCL }, { "make", GEANY_FILETYPES_MAKE }, { "zsh", GEANY_FILETYPES_SH }, { "ksh", GEANY_FILETYPES_SH }, { "mksh", GEANY_FILETYPES_SH }, { "csh", GEANY_FILETYPES_SH }, { "tcsh", GEANY_FILETYPES_SH }, { "ash", GEANY_FILETYPES_SH }, { "dmd", GEANY_FILETYPES_D }, { "wish", GEANY_FILETYPES_TCL }, { "node", GEANY_FILETYPES_JS }, { "rust", GEANY_FILETYPES_RUST } }; gchar *tmp = g_path_get_basename(line + 2); gchar *basename_interpreter = tmp; guint i; if (g_str_has_prefix(tmp, "env ")) { /* skip "env" and read the following interpreter */ basename_interpreter += 4; } for (i = 0; ! ft && i < G_N_ELEMENTS(intepreter_map); i++) { if (g_str_has_prefix(basename_interpreter, intepreter_map[i].name)) ft = filetypes[intepreter_map[i].filetype]; } g_free(tmp); } /* detect HTML files */ if (g_str_has_prefix(line, "message); g_error_free(regex_error); } if (ft != NULL) return ft; if (utf8_filename == NULL) return filetypes[GEANY_FILETYPES_NONE]; return filetypes_detect_from_extension(utf8_filename); } /* Detect the filetype for the document, checking for a shebang, then filename extension. */ GeanyFiletype *filetypes_detect_from_document(GeanyDocument *doc) { GeanyFiletype *ft; gchar *lines[GEANY_FILETYPE_SEARCH_LINES + 1]; gint i; g_return_val_if_fail(doc == NULL || doc->is_valid, filetypes[GEANY_FILETYPES_NONE]); if (doc == NULL) return filetypes[GEANY_FILETYPES_NONE]; for (i = 0; i < GEANY_FILETYPE_SEARCH_LINES; ++i) { lines[i] = sci_get_line(doc->editor->sci, i); } lines[i] = NULL; ft = filetypes_detect_from_file_internal(doc->file_name, lines); for (i = 0; i < GEANY_FILETYPE_SEARCH_LINES; ++i) { g_free(lines[i]); } return ft; } #ifdef HAVE_PLUGINS /* Currently only used by external plugins (e.g. geanyprj). */ /** * Detects filetype based on a shebang line in the file or the filename extension. * * @param utf8_filename The filename in UTF-8 encoding. * * @return @transfer{none} The detected filetype for @a utf8_filename or * @c filetypes[GEANY_FILETYPES_NONE] if it could not be detected. **/ GEANY_API_SYMBOL GeanyFiletype *filetypes_detect_from_file(const gchar *utf8_filename) { gchar line[1024]; gchar *lines[2]; FILE *f; gchar *locale_name = utils_get_locale_from_utf8(utf8_filename); f = g_fopen(locale_name, "r"); g_free(locale_name); if (f != NULL) { if (fgets(line, sizeof(line), f) != NULL) { fclose(f); lines[0] = line; lines[1] = NULL; return filetypes_detect_from_file_internal(utf8_filename, lines); } fclose(f); } return filetypes_detect_from_extension(utf8_filename); } #endif void filetypes_select_radio_item(const GeanyFiletype *ft) { /* ignore_callback has to be set by the caller */ g_return_if_fail(ignore_callback); if (ft == NULL) ft = filetypes[GEANY_FILETYPES_NONE]; gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(ft->priv->menu_item), TRUE); } static void on_filetype_change(GtkCheckMenuItem *menuitem, gpointer user_data) { GeanyDocument *doc = document_get_current(); if (ignore_callback || doc == NULL || ! gtk_check_menu_item_get_active(menuitem)) return; document_set_filetype(doc, (GeanyFiletype*)user_data); } static void create_radio_menu_item(GtkWidget *menu, GeanyFiletype *ftype) { static GSList *group = NULL; GtkWidget *tmp; tmp = gtk_radio_menu_item_new_with_label(group, ftype->title); group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(tmp)); ftype->priv->menu_item = tmp; gtk_widget_show(tmp); gtk_container_add(GTK_CONTAINER(menu), tmp); g_signal_connect(tmp, "activate", G_CALLBACK(on_filetype_change), (gpointer) ftype); } static void filetype_free(gpointer data, G_GNUC_UNUSED gpointer user_data) { GeanyFiletype *ft = data; g_return_if_fail(ft != NULL); g_free(ft->name); g_free(ft->title); g_free(ft->extension); g_free(ft->mime_type); g_free(ft->comment_open); g_free(ft->comment_close); g_free(ft->comment_single); g_free(ft->context_action_cmd); g_free(ft->priv->filecmds); g_free(ft->priv->ftdefcmds); g_free(ft->priv->execcmds); g_free(ft->error_regex_string); if (ft->icon) g_object_unref(ft->icon); g_strfreev(ft->pattern); if (ft->priv->error_regex) g_regex_unref(ft->priv->error_regex); g_slist_foreach(ft->priv->tag_files, (GFunc) g_free, NULL); g_slist_free(ft->priv->tag_files); g_free(ft->priv); g_free(ft); } /* frees the array and all related pointers */ void filetypes_free_types(void) { g_return_if_fail(filetypes_array != NULL); g_return_if_fail(filetypes_hash != NULL); g_ptr_array_foreach(filetypes_array, filetype_free, NULL); g_ptr_array_free(filetypes_array, TRUE); g_hash_table_destroy(filetypes_hash); } static void load_indent_settings(GeanyFiletype *ft, GKeyFile *config, GKeyFile *configh) { ft->indent_width = utils_get_setting(integer, configh, config, "indentation", "width", -1); ft->indent_type = utils_get_setting(integer, configh, config, "indentation", "type", -1); /* check whether the indent type is OK */ switch (ft->indent_type) { case GEANY_INDENT_TYPE_TABS: case GEANY_INDENT_TYPE_SPACES: case GEANY_INDENT_TYPE_BOTH: case -1: break; default: g_warning("Invalid indent type %d in file type %s", ft->indent_type, ft->name); ft->indent_type = -1; break; } } static void load_settings(guint ft_id, GKeyFile *config, GKeyFile *configh) { GeanyFiletype *ft = filetypes[ft_id]; gchar *result; /* default extension */ result = utils_get_setting(string, configh, config, "settings", "extension", NULL); if (result != NULL) { SETPTR(filetypes[ft_id]->extension, result); } /* MIME type */ result = utils_get_setting(string, configh, config, "settings", "mime_type", "text/plain"); SETPTR(filetypes[ft_id]->mime_type, result); /* read comment notes */ result = utils_get_setting(string, configh, config, "settings", "comment_open", NULL); if (result != NULL) { SETPTR(filetypes[ft_id]->comment_open, result); } result = utils_get_setting(string, configh, config, "settings", "comment_close", NULL); if (result != NULL) { SETPTR(filetypes[ft_id]->comment_close, result); } result = utils_get_setting(string, configh, config, "settings", "comment_single", NULL); if (result != NULL) { SETPTR(filetypes[ft_id]->comment_single, result); } /* import correctly filetypes that use old-style single comments */ else if (EMPTY(filetypes[ft_id]->comment_close)) { SETPTR(filetypes[ft_id]->comment_single, filetypes[ft_id]->comment_open); filetypes[ft_id]->comment_open = NULL; } filetypes[ft_id]->comment_use_indent = utils_get_setting(boolean, configh, config, "settings", "comment_use_indent", FALSE); /* read context action */ result = utils_get_setting(string, configh, config, "settings", "context_action_cmd", NULL); if (result != NULL) { SETPTR(filetypes[ft_id]->context_action_cmd, result); } result = utils_get_setting(string, configh, config, "settings", "tag_parser", NULL); if (result != NULL) { ft->lang = tm_source_file_get_named_lang(result); if (ft->lang == TM_PARSER_NONE) geany_debug("Cannot find tags parser '%s' for custom filetype '%s'.", result, ft->name); g_free(result); } result = utils_get_setting(string, configh, config, "settings", "lexer_filetype", NULL); if (result != NULL) { ft->lexer_filetype = filetypes_lookup_by_name(result); if (!ft->lexer_filetype) geany_debug("Cannot find lexer filetype '%s' for custom filetype '%s'.", result, ft->name); g_free(result); } ft->priv->symbol_list_sort_mode = utils_get_setting(integer, configh, config, "settings", "symbol_list_sort_mode", SYMBOLS_SORT_USE_PREVIOUS); ft->priv->xml_indent_tags = utils_get_setting(boolean, configh, config, "settings", "xml_indent_tags", FALSE); /* read indent settings */ load_indent_settings(ft, config, configh); /* read build settings */ build_load_menu(config, GEANY_BCS_FT, (gpointer)ft); build_load_menu(configh, GEANY_BCS_HOME_FT, (gpointer)ft); } static void copy_keys(GKeyFile *dest, const gchar *dest_group, GKeyFile *src, const gchar *src_group) { gchar **keys = g_key_file_get_keys(src, src_group, NULL, NULL); gchar **ptr; foreach_strv(ptr, keys) { gchar *key = *ptr; gchar *value = g_key_file_get_value(src, src_group, key, NULL); g_key_file_set_value(dest, dest_group, key, value); g_free(value); } g_strfreev(keys); } static gchar *filetypes_get_filename(GeanyFiletype *ft, gboolean user) { gchar *ext = filetypes_get_conf_extension(ft); gchar *base_name = g_strconcat("filetypes.", ext, NULL); gchar *file_name; if (user) file_name = g_build_filename(app->configdir, GEANY_FILEDEFS_SUBDIR, base_name, NULL); else file_name = g_build_filename(app->datadir, GEANY_FILEDEFS_SUBDIR, base_name, NULL); g_free(ext); g_free(base_name); return file_name; } static void add_group_keys(GKeyFile *kf, const gchar *group, GeanyFiletype *ft) { gchar *files[2]; gboolean loaded = FALSE; guint i; files[0] = filetypes_get_filename(ft, FALSE); files[1] = filetypes_get_filename(ft, TRUE); for (i = 0; i < G_N_ELEMENTS(files); i++) { GKeyFile *src = g_key_file_new(); if (g_key_file_load_from_file(src, files[i], G_KEY_FILE_NONE, NULL)) { copy_keys(kf, group, src, group); loaded = TRUE; } g_key_file_free(src); } if (!loaded) geany_debug("Could not read config file %s for [%s=%s]!", files[0], group, ft->name); g_free(files[0]); g_free(files[1]); } static void copy_ft_groups(GKeyFile *kf) { gchar **groups = g_key_file_get_groups(kf, NULL); gchar **ptr; foreach_strv(ptr, groups) { gchar *group = *ptr; gchar *old_group; gchar *name = strchr(*ptr, '='); GeanyFiletype *ft; if (!name || !name[1]) /* no name or no parent name */ continue; old_group = g_strdup(group); /* terminate group at '=' */ *name = 0; name++; ft = filetypes_lookup_by_name(name); if (ft) { add_group_keys(kf, group, ft); /* move old group keys (foo=bar) to proper group name (foo) */ copy_keys(kf, group, kf, old_group); } g_free(old_group); } g_strfreev(groups); } /* simple wrapper function to print file errors in DEBUG mode */ static void load_system_keyfile(GKeyFile *key_file, const gchar *file, GKeyFileFlags flags, GeanyFiletype *ft) { GError *error = NULL; gboolean done = g_key_file_load_from_file(key_file, file, flags, &error); if (error != NULL) { if (!done && !ft->priv->custom) geany_debug("Failed to open %s (%s)", file, error->message); g_error_free(error); error = NULL; } } /* Load the configuration file for the associated filetype id. * This should only be called when the filetype is needed, to save loading * 20+ configuration files all at once. */ void filetypes_load_config(guint ft_id, gboolean reload) { GKeyFile *config, *config_home; GeanyFiletypePrivate *pft; GeanyFiletype *ft; g_return_if_fail(ft_id < filetypes_array->len); ft = filetypes[ft_id]; pft = ft->priv; /* when reloading, proceed only if the settings were already loaded */ if (G_UNLIKELY(reload && ! pft->keyfile_loaded)) return; /* when not reloading, load the settings only once */ if (G_LIKELY(! reload && pft->keyfile_loaded)) return; pft->keyfile_loaded = TRUE; config = g_key_file_new(); config_home = g_key_file_new(); { /* highlighting uses GEANY_FILETYPES_NONE for common settings */ gchar *f; f = filetypes_get_filename(ft, FALSE); load_system_keyfile(config, f, G_KEY_FILE_KEEP_COMMENTS, ft); SETPTR(f, filetypes_get_filename(ft, TRUE)); g_key_file_load_from_file(config_home, f, G_KEY_FILE_KEEP_COMMENTS, NULL); g_free(f); } /* Copy keys for any groups with [group=C] from system keyfile */ copy_ft_groups(config); copy_ft_groups(config_home); load_settings(ft_id, config, config_home); highlighting_init_styles(ft_id, config, config_home); if (ft->icon) g_object_unref(ft->icon); ft->icon = ui_get_mime_icon(ft->mime_type); g_key_file_free(config); g_key_file_free(config_home); } static gchar *filetypes_get_conf_extension(const GeanyFiletype *ft) { gchar *result; if (ft->priv->custom) return g_strconcat(ft->name, ".conf", NULL); /* Handle any special extensions different from lowercase filetype->name */ switch (ft->id) { case GEANY_FILETYPES_CPP: result = g_strdup("cpp"); break; case GEANY_FILETYPES_CS: result = g_strdup("cs"); break; case GEANY_FILETYPES_MAKE: result = g_strdup("makefile"); break; case GEANY_FILETYPES_NONE: result = g_strdup("common"); break; /* name is Matlab/Octave */ case GEANY_FILETYPES_MATLAB: result = g_strdup("matlab"); break; /* name is Objective-C, and we don't want the hyphen */ case GEANY_FILETYPES_OBJECTIVEC: result = g_strdup("objectivec"); break; default: result = g_ascii_strdown(ft->name, -1); break; } return result; } void filetypes_save_commands(GeanyFiletype *ft) { GKeyFile *config_home; gchar *fname, *data; fname = filetypes_get_filename(ft, TRUE); config_home = g_key_file_new(); g_key_file_load_from_file(config_home, fname, G_KEY_FILE_KEEP_COMMENTS, NULL); build_save_menu(config_home, ft, GEANY_BCS_HOME_FT); data = g_key_file_to_data(config_home, NULL, NULL); utils_write_file(fname, data); g_free(data); g_key_file_free(config_home); g_free(fname); } /* create one file filter which has each file pattern of each filetype */ GtkFileFilter *filetypes_create_file_filter_all_source(void) { GtkFileFilter *new_filter; guint i, j; new_filter = gtk_file_filter_new(); gtk_file_filter_set_name(new_filter, _("All Source")); for (i = 0; i < filetypes_array->len; i++) { if (G_UNLIKELY(i == GEANY_FILETYPES_NONE)) continue; for (j = 0; filetypes[i]->pattern[j]; j++) { gtk_file_filter_add_pattern(new_filter, filetypes[i]->pattern[j]); } } return new_filter; } GtkFileFilter *filetypes_create_file_filter(const GeanyFiletype *ft) { GtkFileFilter *new_filter; gint i; const gchar *title; g_return_val_if_fail(ft != NULL, NULL); new_filter = gtk_file_filter_new(); title = ft->id == GEANY_FILETYPES_NONE ? _("All files") : ft->title; gtk_file_filter_set_name(new_filter, title); for (i = 0; ft->pattern[i]; i++) { gtk_file_filter_add_pattern(new_filter, ft->pattern[i]); } return new_filter; } /* Indicates whether there is a tag parser for the filetype or not. * Only works for custom filetypes if the filetype settings have been loaded. */ gboolean filetype_has_tags(GeanyFiletype *ft) { g_return_val_if_fail(ft != NULL, FALSE); return ft->lang != TM_PARSER_NONE; } /** Finds a filetype pointer from its @a name field. * @param name Filetype name. * @return @transfer{none} @nullable The filetype found, or @c NULL. * * @since 0.15 **/ GEANY_API_SYMBOL GeanyFiletype *filetypes_lookup_by_name(const gchar *name) { GeanyFiletype *ft; g_return_val_if_fail(!EMPTY(name), NULL); ft = g_hash_table_lookup(filetypes_hash, name); if (G_UNLIKELY(ft == NULL)) geany_debug("Could not find filetype '%s'.", name); return ft; } static void compile_regex(GeanyFiletype *ft, gchar *regstr) { GError *error = NULL; GRegex *regex = g_regex_new(regstr, 0, 0, &error); if (!regex) { ui_set_statusbar(TRUE, _("Bad regex for filetype %s: %s"), filetypes_get_display_name(ft), error->message); g_error_free(error); } if (ft->priv->error_regex) g_regex_unref(ft->priv->error_regex); ft->priv->error_regex = regex; } gboolean filetypes_parse_error_message(GeanyFiletype *ft, const gchar *message, gchar **filename, gint *line) { gchar *regstr; gchar **tmp; GeanyDocument *doc; GMatchInfo *minfo; gint i, n_match_groups; gchar *first, *second; if (ft == NULL) { doc = document_get_current(); if (doc != NULL) ft = doc->file_type; } tmp = build_get_regex(build_info.grp, ft, NULL); if (tmp == NULL) return FALSE; regstr = *tmp; *filename = NULL; *line = -1; if (G_UNLIKELY(EMPTY(regstr))) return FALSE; if (!ft->priv->error_regex || regstr != ft->priv->last_error_pattern) { compile_regex(ft, regstr); ft->priv->last_error_pattern = regstr; } if (!ft->priv->error_regex) return FALSE; if (!g_regex_match(ft->priv->error_regex, message, 0, &minfo)) { g_match_info_free(minfo); return FALSE; } n_match_groups = g_match_info_get_match_count(minfo); first = second = NULL; for (i = 1; i < n_match_groups; i++) { gint start_pos; g_match_info_fetch_pos(minfo, i, &start_pos, NULL); if (start_pos != -1) { if (first == NULL) first = g_match_info_fetch(minfo, i); else { second = g_match_info_fetch(minfo, i); break; } } } if (second) { gchar *end; glong l; l = strtol(first, &end, 10); if (*end == '\0') /* first is purely decimals */ { *line = l; g_free(first); *filename = second; } else { l = strtol(second, &end, 10); if (*end == '\0') { *line = l; g_free(second); *filename = first; } else { g_free(first); g_free(second); } } } else g_free(first); g_match_info_free(minfo); return *filename != NULL; } #ifdef G_OS_WIN32 static void convert_filetype_extensions_to_lower_case(gchar **patterns, gsize len) { guint i; for (i = 0; i < len; i++) { SETPTR(patterns[i], g_ascii_strdown(patterns[i], -1)); } } #endif static void read_extensions(GKeyFile *sysconfig, GKeyFile *userconfig) { guint i; gsize len = 0; /* read the keys */ for (i = 0; i < filetypes_array->len; i++) { gboolean userset = g_key_file_has_key(userconfig, "Extensions", filetypes[i]->name, NULL); gchar **list = g_key_file_get_string_list( (userset) ? userconfig : sysconfig, "Extensions", filetypes[i]->name, &len, NULL); filetypes[i]->priv->user_extensions = userset; g_strfreev(filetypes[i]->pattern); /* Note: we allow 'Foo=' to remove all patterns */ if (!list) list = g_new0(gchar*, 1); filetypes[i]->pattern = list; #ifdef G_OS_WIN32 convert_filetype_extensions_to_lower_case(filetypes[i]->pattern, len); #endif } } static void read_group(GKeyFile *config, const gchar *group_name, GeanyFiletypeGroupID group_id) { gchar **names = g_key_file_get_string_list(config, "Groups", group_name, NULL, NULL); gchar **name; foreach_strv(name, names) { GeanyFiletype *ft = filetypes_lookup_by_name(*name); if (ft) { ft->group = group_id; if (ft->priv->custom && (group_id == GEANY_FILETYPE_GROUP_COMPILED || group_id == GEANY_FILETYPE_GROUP_SCRIPT)) { SETPTR(ft->title, filetype_make_title(ft->name, TITLE_SOURCE_FILE)); } } else geany_debug("Filetype '%s' not found for group '%s'!", *name, group_name); } g_strfreev(names); } static void read_groups(GKeyFile *config) { read_group(config, "Programming", GEANY_FILETYPE_GROUP_COMPILED); read_group(config, "Script", GEANY_FILETYPE_GROUP_SCRIPT); read_group(config, "Markup", GEANY_FILETYPE_GROUP_MARKUP); read_group(config, "Misc", GEANY_FILETYPE_GROUP_MISC); read_group(config, "None", GEANY_FILETYPE_GROUP_NONE); } static void read_filetype_config(void) { gchar *sysconfigfile = g_build_filename(app->datadir, "filetype_extensions.conf", NULL); gchar *userconfigfile = g_build_filename(app->configdir, "filetype_extensions.conf", NULL); GKeyFile *sysconfig = g_key_file_new(); GKeyFile *userconfig = g_key_file_new(); g_key_file_load_from_file(sysconfig, sysconfigfile, G_KEY_FILE_NONE, NULL); g_key_file_load_from_file(userconfig, userconfigfile, G_KEY_FILE_NONE, NULL); read_extensions(sysconfig, userconfig); read_groups(sysconfig); read_groups(userconfig); g_free(sysconfigfile); g_free(userconfigfile); g_key_file_free(sysconfig); g_key_file_free(userconfig); } void filetypes_reload_extensions(void) { guint i; read_filetype_config(); /* Redetect filetype of any documents with none set */ foreach_document(i) { GeanyDocument *doc = documents[i]; if (doc->file_type->id != GEANY_FILETYPES_NONE) continue; document_set_filetype(doc, filetypes_detect_from_document(doc)); } } /** Accessor function for @ref GeanyData::filetypes_array items. * Example: @code ft = filetypes_index(GEANY_FILETYPES_C); @endcode * @param idx @c filetypes_array index. * @return @transfer{none} @nullable The filetype, or @c NULL if @a idx is out of range. * * @since 0.16 */ GEANY_API_SYMBOL GeanyFiletype *filetypes_index(gint idx) { return (idx >= 0 && idx < (gint) filetypes_array->len) ? filetypes[idx] : NULL; } void filetypes_reload(void) { guint i; GeanyDocument *current_doc; /* reload filetype configs */ for (i = 0; i < filetypes_array->len; i++) { /* filetypes_load_config() will skip not loaded filetypes */ filetypes_load_config(i, TRUE); } current_doc = document_get_current(); if (!current_doc) return; /* update document styling */ foreach_document(i) { if (current_doc != documents[i]) document_reload_config(documents[i]); } /* process the current document at last */ document_reload_config(current_doc); } /** Gets @c ft->name or a translation for filetype None. * @param ft . * @return . * @since Geany 0.20 */ GEANY_API_SYMBOL const gchar *filetypes_get_display_name(GeanyFiletype *ft) { return ft->id == GEANY_FILETYPES_NONE ? _("None") : ft->name; } /* gets comment_open/comment_close/comment_single strings from the filetype * @param single_first: whether single comment is preferred if both available * returns true if at least comment_open is set, false otherwise */ gboolean filetype_get_comment_open_close(const GeanyFiletype *ft, gboolean single_first, const gchar **co, const gchar **cc) { g_return_val_if_fail(ft != NULL, FALSE); g_return_val_if_fail(co != NULL, FALSE); g_return_val_if_fail(cc != NULL, FALSE); if (single_first) { *co = ft->comment_single; if (!EMPTY(*co)) *cc = NULL; else { *co = ft->comment_open; *cc = ft->comment_close; } } else { *co = ft->comment_open; if (!EMPTY(*co)) *cc = ft->comment_close; else { *co = ft->comment_single; *cc = NULL; } } return !EMPTY(*co); } static void *copy_(void *src) { return src; } static void free_(void *doc) { } /** @gironly * Gets the GType of GeanyFiletype * * @return the GeanyFiletype type */ GEANY_API_SYMBOL GType filetype_get_type (void); G_DEFINE_BOXED_TYPE(GeanyFiletype, filetype, copy_, free_); geany-2.0/src/project.h0000644000175000017500000000507314514252267012022 00000000000000/* * project.h - this file is part of Geany, a fast and lightweight IDE * * Copyright 2007 The Geany contributors * * This program 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; either version 2 of the License, or * (at your option) any later version. * * This program 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef GEANY_PROJECT_H #define GEANY_PROJECT_H 1 #include #include G_BEGIN_DECLS #define GEANY_PROJECT_EXT "geany" /** Structure for representing a project. */ typedef struct GeanyProject { gchar *name; /**< The name of the project. */ gchar *description; /**< Short description of the project. */ gchar *file_name; /**< Where the project file is stored (in UTF-8). */ gchar *base_path; /**< Base path of the project directory (in UTF-8, maybe relative). */ /** Identifier whether it is a pure Geany project or modified/extended * by a plugin. */ gint type; GStrv file_patterns; /**< Array of filename extension patterns. */ struct GeanyProjectPrivate *priv; /* must be last, append fields before this item */ } GeanyProject; void project_write_config(void); #ifdef GEANY_PRIVATE typedef struct ProjectPrefs { gchar *session_file; gboolean project_file_in_basedir; } ProjectPrefs; extern ProjectPrefs project_prefs; void project_init(void); void project_finalize(void); void project_new(gboolean from_folder); void project_open(void); gboolean project_close(gboolean open_default); void project_properties(void); void project_build_properties(void); gboolean project_ask_close(void); gboolean project_load_file(const gchar *locale_file_name); gboolean project_load_file_with_session(const gchar *locale_file_name); gchar *project_get_base_path(void); const struct GeanyFilePrefs *project_get_file_prefs(void); void project_save_prefs(GKeyFile *config); void project_load_prefs(GKeyFile *config); void project_setup_prefs(void); void project_apply_prefs(void); #endif /* GEANY_PRIVATE */ G_END_DECLS #endif /* GEANY_PROJECT_H */ geany-2.0/src/log.h0000644000175000017500000000214014514252267011125 00000000000000/* * log.h - this file is part of Geany, a fast and lightweight IDE * * Copyright 2008 The Geany contributors * * This program 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; either version 2 of the License, or * (at your option) any later version. * * This program 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef GEANY_LOG_H #define GEANY_LOG_H 1 #include G_BEGIN_DECLS void log_handlers_init(void); void log_finalize(void); void log_show_debug_messages_dialog(void); G_END_DECLS #endif /* GEANY_LOG_H */ geany-2.0/src/socket.c0000644000175000017500000005350514514252267011642 00000000000000/* * socket.c - this file is part of Geany, a fast and lightweight IDE * * Copyright 2006 The Geany contributors * Copyright 2006 Hiroyuki Yamamoto (author of Sylpheed) * * This program 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; either version 2 of the License, or * (at your option) any later version. * * This program 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /* * Socket setup and messages handling. * The socket allows detection and messages to be sent to the first running instance of Geany. * Only the first instance loads session files at startup, and opens files from the command-line. */ /* * Little dev doc: * Each command which is sent between two instances (see send_open_command and * socket_lock_input_cb) should have the following scheme: * command name\n * data\n * data\n * ... * .\n * The first thing should be the command name followed by the data belonging to the command and * to mark the end of data send a single '.'. Each message should be ended with \n. * The command window is only available on Windows and takes no additional data, instead it * writes back a Windows handle (HWND) for the main window to set it to the foreground (focus). * * At the moment the commands window, doclist, open, openro, line and column are available. * * About the socket files on Unix-like systems: * Geany creates a socket in /tmp (or any other directory returned by g_get_tmp_dir()) and * a symlink in the current configuration to the created socket file. The symlink is named * geany_socket__ (displayname is the name of the active X display). * If the socket file cannot be created in the temporary directory, Geany creates the socket file * directly in the configuration directory as a fallback. * */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #ifdef HAVE_SOCKET #include "socket.h" #include "app.h" #include "dialogs.h" #include "document.h" #include "encodings.h" #include "main.h" #include "support.h" #include "utils.h" #include "win32.h" #include #ifndef G_OS_WIN32 # include # include # include # include # include # include #else # include # include # include # include #endif #include #include #include #include #include #ifdef GDK_WINDOWING_X11 #include #endif #ifdef G_OS_WIN32 #define SOCKET_IS_VALID(s) ((s) != INVALID_SOCKET) #else #define SOCKET_IS_VALID(s) ((s) >= 0) #define INVALID_SOCKET (-1) #endif #define BUFFER_LENGTH 4096 struct SocketInfo socket_info; #ifdef G_OS_WIN32 static gint socket_fd_connect_inet (gushort port); static gint socket_fd_open_inet (gushort port); static void socket_init_win32 (void); #else static gint socket_fd_connect_unix (const gchar *path); static gint socket_fd_open_unix (const gchar *path); #endif static gint socket_fd_write (gint sock, const gchar *buf, gint len); static gint socket_fd_write_all (gint sock, const gchar *buf, gint len); static gint socket_fd_gets (gint sock, gchar *buf, gint len); static gint socket_fd_check_io (gint fd, GIOCondition cond); static gint socket_fd_read (gint sock, gchar *buf, gint len); static gint socket_fd_recv (gint fd, gchar *buf, gint len, gint flags); static gint socket_fd_close (gint sock); static void send_open_command(gint sock, gint argc, gchar **argv) { gint i; g_return_if_fail(argc > 1); geany_debug("using running instance of Geany"); if (cl_options.goto_line >= 0) { gchar *line = g_strdup_printf("%d\n", cl_options.goto_line); socket_fd_write_all(sock, "line\n", 5); socket_fd_write_all(sock, line, strlen(line)); socket_fd_write_all(sock, ".\n", 2); g_free(line); } if (cl_options.goto_column >= 0) { gchar *col = g_strdup_printf("%d\n", cl_options.goto_column); socket_fd_write_all(sock, "column\n", 7); socket_fd_write_all(sock, col, strlen(col)); socket_fd_write_all(sock, ".\n", 2); g_free(col); } if (cl_options.readonly) /* append "ro" to denote readonly status for new docs */ socket_fd_write_all(sock, "openro\n", 7); else socket_fd_write_all(sock, "open\n", 5); for (i = 1; i < argc && argv[i] != NULL; i++) { gchar *filename = main_get_argv_filename(argv[i]); /* if the filename is valid or if a new file should be opened is check on the other side */ if (filename != NULL) { socket_fd_write_all(sock, filename, strlen(filename)); socket_fd_write_all(sock, "\n", 1); } else { g_printerr(_("Could not find file '%s'."), filename); g_printerr("\n"); /* keep translation from open_cl_files() in main.c. */ } g_free(filename); } socket_fd_write_all(sock, ".\n", 2); } #ifndef G_OS_WIN32 static void remove_socket_link_full(void) { gchar real_path[512]; gsize len; real_path[0] = '\0'; /* read the contents of the symbolic link socket_info.file_name and delete it * readlink should return something like "/tmp/geany_socket.499602d2" */ len = readlink(socket_info.file_name, real_path, sizeof(real_path) - 1); if ((gint) len > 0) { real_path[len] = '\0'; g_unlink(real_path); } g_unlink(socket_info.file_name); } #endif static void socket_get_document_list(gint sock) { gchar buf[BUFFER_LENGTH]; gint n_read; if (sock < 0) return; socket_fd_write_all(sock, "doclist\n", 8); do { n_read = socket_fd_read(sock, buf, BUFFER_LENGTH); /* if we received ETX (end-of-text), there is nothing else to read, so cut that * byte not to output it and to be sure not to validate the loop condition */ if (n_read > 0 && buf[n_read - 1] == '\3') n_read--; if (n_read > 0) fwrite(buf, 1, n_read, stdout); } while (n_read >= BUFFER_LENGTH); } #ifndef G_OS_WIN32 static void check_socket_permissions(void) { GStatBuf socket_stat; if (g_lstat(socket_info.file_name, &socket_stat) == 0) { /* If the user id of the process is not the same as the owner of the socket * file, then ignore this socket and start a new session. */ if (socket_stat.st_uid != getuid()) { const gchar *msg = _( /* TODO maybe this message needs a rewording */ "Geany tried to access the Unix Domain socket of another instance running as another user.\n" "This is a fatal error and Geany will now quit."); g_warning("%s", msg); dialogs_show_msgbox(GTK_MESSAGE_ERROR, "%s", msg); exit(1); } } } #endif /* (Unix domain) socket support to replace the old FIFO code * (taken from Sylpheed, thanks) * Returns the created socket, -1 if an error occurred or -2 if another socket exists and files * were sent to it. */ gint socket_init(gint argc, gchar **argv, G_GNUC_UNUSED gushort socket_port) { gint sock; #ifdef G_OS_WIN32 HANDLE hmutex; HWND hwnd; socket_init_win32(); hmutex = CreateMutexA(NULL, FALSE, "Geany"); if (! hmutex) { geany_debug("cannot create Mutex\n"); return -1; } if (GetLastError() != ERROR_ALREADY_EXISTS) { /* To support multiple instances with different configuration directories (as we do on * non-Windows systems) we would need to use different port number s but it might be * difficult to get a port number which is unique for a configuration directory (path) * and which is unused. This port number has to be guessed by the first and new instance * and the only data is the configuration directory path. * For now we use one port number, that is we support only one instance at all. */ sock = socket_fd_open_inet(socket_port); if (sock < 0) return -1; return sock; } sock = socket_fd_connect_inet(socket_port); if (sock < 0) return -1; #else gchar *display_name = NULL; const gchar *hostname = g_get_host_name(); GdkDisplay *display = gdk_display_get_default(); gchar *p; /* On OS X with quartz backend gdk_display_get_name() returns hostname * using [NSHost currentHost] (it could return more or less whatever string * as display name is a X11 specific thing). This call can lead to network * query and block for several seconds so better skip it. */ #ifndef GDK_WINDOWING_QUARTZ if (display != NULL) display_name = g_strdup(gdk_display_get_name(display)); #endif if (display_name == NULL) display_name = g_strdup("NODISPLAY"); /* these lines are taken from dcopc.c in kdelibs */ if ((p = strrchr(display_name, '.')) > strrchr(display_name, ':') && p != NULL) *p = '\0'; /* remove characters that may not be acceptable in a filename */ for (p = display_name; *p; p++) { if (*p == ':' || *p == '/') *p = '_'; } if (socket_info.file_name == NULL) socket_info.file_name = g_strdup_printf("%s%cgeany_socket_%s_%s", app->configdir, G_DIR_SEPARATOR, hostname, display_name); g_free(display_name); /* check whether the real user id is the same as this of the socket file */ check_socket_permissions(); sock = socket_fd_connect_unix(socket_info.file_name); if (sock < 0) { remove_socket_link_full(); /* deletes the socket file and the symlink */ return socket_fd_open_unix(socket_info.file_name); } #endif /* remote command mode, here we have another running instance and want to use it */ /* now we send the command line args */ if (argc > 1) { #ifdef G_OS_WIN32 /* first we send a request to retrieve the window handle and focus the window */ socket_fd_write_all(sock, "window\n", 7); if (socket_fd_read(sock, (gchar *)&hwnd, sizeof(hwnd)) == sizeof(hwnd)) SetForegroundWindow(hwnd); #endif send_open_command(sock, argc, argv); } if (cl_options.list_documents) { socket_get_document_list(sock); } socket_fd_close(sock); return -2; } gint socket_finalize(void) { if (socket_info.lock_socket < 0) return -1; if (socket_info.lock_socket_tag > 0) g_source_remove(socket_info.lock_socket_tag); if (socket_info.read_ioc) { g_io_channel_shutdown(socket_info.read_ioc, FALSE, NULL); g_io_channel_unref(socket_info.read_ioc); socket_info.read_ioc = NULL; } #ifdef G_OS_WIN32 WSACleanup(); #else if (socket_info.file_name != NULL) { remove_socket_link_full(); /* deletes the socket file and the symlink */ g_free(socket_info.file_name); } #endif return 0; } static void log_error(const gchar *message_prefix, gint error_code) { #ifdef G_OS_WIN32 error_code = error_code == -1 ? WSAGetLastError(): error_code; gchar *error_message = g_win32_error_message(error_code); #else error_code = error_code == -1 ? errno: error_code; gchar *error_message = g_strdup(g_strerror(error_code)); #endif g_warning("%s: %d: %s", message_prefix, error_code, error_message); g_free(error_message); } #ifdef G_OS_UNIX static gint socket_fd_connect_unix(const gchar *path) { gint sock; struct sockaddr_un addr; sock = socket(PF_UNIX, SOCK_STREAM, 0); if (sock < 0) { log_error("Failed to create IPC socket", errno); return -1; } memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; strncpy(addr.sun_path, path, sizeof(addr.sun_path) - 1); if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) { socket_fd_close(sock); return -1; } return sock; } static gint socket_fd_open_unix(const gchar *path) { gint sock; struct sockaddr_un addr; gint val, err; gchar *real_dir; gchar *real_path; gchar *basename; sock = socket(PF_UNIX, SOCK_STREAM, 0); if (sock < 0) { log_error("Failed to create IPC socket", errno); return -1; } val = 1; if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) < 0) { log_error("Failed to set IPC socket option", errno); socket_fd_close(sock); return -1; } /* Try to place the socket in XDG_RUNTIME_DIR, according to XDG Base * Directory Specification, see * https://specifications.freedesktop.org/basedir-spec/latest. * If that fails, we try to use /tmp as a fallback. The last resort * is the configuration directory. But the other directories * are preferred in case the configuration directory is located on * a network file system or any other file system which doesn't * support sockets (see #1888561). Append a random int to * prevent clashes with other instances on the system. */ real_dir = g_build_filename(g_get_user_runtime_dir(), "geany", NULL); err = utils_mkdir(real_dir, FALSE); basename = g_strdup_printf("geany_socket.%08x", g_random_int()); if (err == 0 || err == EEXIST) real_path = g_build_filename(real_dir, basename, NULL); else real_path = g_build_filename(g_get_tmp_dir(), basename, NULL); g_free(basename); g_free(real_dir); if (utils_is_file_writable(real_path) != 0) { /* if real_path is not writable for us, fall back to ~/.config/geany/geany_socket_*_* */ /* instead of creating a symlink and print a warning */ g_warning("Socket %s could not be written, using %s as fallback.", real_path, path); SETPTR(real_path, g_strdup(path)); } /* create a symlink in e.g. ~/.config/geany/geany_socket_hostname__0 to * /var/run/user/1000/geany/geany_socket.* */ else if (symlink(real_path, path) != 0) { gint saved_errno = errno; gchar* message = g_strdup_printf( "Failed to create IPC socket symlink %s -> %s)", real_path, path); log_error(message, saved_errno); g_free(message); socket_fd_close(sock); return -1; } memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; strncpy(addr.sun_path, real_path, sizeof(addr.sun_path) - 1); if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) { gint saved_errno = errno; gchar* message = g_strdup_printf("Failed to bind IPC socket (%s)", real_path); log_error(message, saved_errno); g_free(message); socket_fd_close(sock); return -1; } if (listen(sock, 1) < 0) { gint saved_errno = errno; gchar* message = g_strdup_printf("Failed to listen on IPC socket (%s)", real_path); log_error(message, saved_errno); g_free(message); socket_fd_close(sock); return -1; } g_chmod(real_path, 0600); g_free(real_path); return sock; } #endif static gint socket_fd_close(gint fd) { #ifdef G_OS_WIN32 return closesocket(fd); #else return close(fd); #endif } #ifdef G_OS_WIN32 static gint socket_fd_open_inet(gushort port) { SOCKET sock; struct sockaddr_in addr; gchar val; sock = socket(AF_INET, SOCK_STREAM, 0); if (G_UNLIKELY(! SOCKET_IS_VALID(sock))) { log_error("Failed to create IPC socket", -1); return -1; } val = 1; if (setsockopt(sock, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, &val, sizeof(val)) < 0) { log_error("Failed to set IPC socket exclusive option", -1); socket_fd_close(sock); return -1; } memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_port = htons(port); addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) { gint saved_errno = WSAGetLastError(); gchar* message = g_strdup_printf("Failed to bind IPC socket (127.0.0.1:%d)", port); log_error(message, saved_errno); g_free(message); socket_fd_close(sock); return -1; } if (listen(sock, 1) < 0) { gint saved_errno = WSAGetLastError(); gchar* message = g_strdup_printf("Failed to listen on IPC socket (127.0.0.1:%d)", port); log_error(message, saved_errno); g_free(message); socket_fd_close(sock); return -1; } return sock; } static gint socket_fd_connect_inet(gushort port) { SOCKET sock; struct sockaddr_in addr; sock = socket(AF_INET, SOCK_STREAM, 0); if (G_UNLIKELY(! SOCKET_IS_VALID(sock))) { log_error("Failed to create IPC socket", -1); return -1; } memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_port = htons(port); addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) { gint saved_errno = WSAGetLastError(); gchar* message = g_strdup_printf("Failed to connect to IPC socket (127.0.0.1:%d)", port); log_error(message, saved_errno); g_free(message); socket_fd_close(sock); return -1; } return sock; } static void socket_init_win32(void) { WSADATA wsadata; if (WSAStartup(MAKEWORD(2, 2), &wsadata) != NO_ERROR) geany_debug("WSAStartup() failed\n"); return; } #endif static void handle_input_filename(const gchar *buf) { gchar *utf8_filename, *locale_filename; /* we never know how the input is encoded, so do the best auto detection we can */ if (! g_utf8_validate(buf, -1, NULL)) utf8_filename = encodings_convert_to_utf8(buf, -1, NULL); else utf8_filename = g_strdup(buf); locale_filename = utils_get_locale_from_utf8(utf8_filename); if (locale_filename) { if (g_str_has_suffix(locale_filename, ".geany")) { if (project_ask_close()) main_load_project_from_command_line(locale_filename, TRUE); } else main_handle_filename(locale_filename); } g_free(utf8_filename); g_free(locale_filename); } static gchar *build_document_list(void) { GString *doc_list = g_string_new(NULL); guint i; const gchar *filename; foreach_document(i) { filename = DOC_FILENAME(documents[i]); g_string_append(doc_list, filename); g_string_append_c(doc_list, '\n'); } return g_string_free(doc_list, FALSE); } gboolean socket_lock_input_cb(GIOChannel *source, GIOCondition condition, gpointer data) { gint fd, sock; gchar buf[BUFFER_LENGTH]; gchar *command = NULL; struct sockaddr_in caddr; socklen_t caddr_len = sizeof(caddr); GtkWidget *window = data; gboolean popup = FALSE; fd = g_io_channel_unix_get_fd(source); sock = accept(fd, (struct sockaddr *)&caddr, &caddr_len); /* first get the command */ while (socket_fd_gets(sock, buf, sizeof(buf)) != -1) { command = g_strdup(buf); geany_debug("Received IPC command from remote instance: %s", g_strstrip(command)); g_free(command); if (strncmp(buf, "open", 4) == 0) { cl_options.readonly = strncmp(buf+4, "ro", 2) == 0; /* open in readonly? */ while (socket_fd_gets(sock, buf, sizeof(buf)) != -1 && *buf != '.') { gsize buf_len = strlen(buf); /* remove trailing newline */ if (buf_len > 0 && buf[buf_len - 1] == '\n') buf[buf_len - 1] = '\0'; handle_input_filename(buf); } popup = TRUE; } else if (strncmp(buf, "doclist", 7) == 0) { gchar *doc_list = build_document_list(); if (!EMPTY(doc_list)) socket_fd_write_all(sock, doc_list, strlen(doc_list)); /* send ETX (end-of-text) so reader knows to stop reading */ socket_fd_write_all(sock, "\3", 1); g_free(doc_list); } else if (strncmp(buf, "line", 4) == 0) { while (socket_fd_gets(sock, buf, sizeof(buf)) != -1 && *buf != '.') { g_strstrip(buf); /* remove \n char */ /* on any error we get 0 which should be safe enough as fallback */ cl_options.goto_line = atoi(buf); } } else if (strncmp(buf, "column", 6) == 0) { while (socket_fd_gets(sock, buf, sizeof(buf)) != -1 && *buf != '.') { g_strstrip(buf); /* remove \n char */ /* on any error we get 0 which should be safe enough as fallback */ cl_options.goto_column = atoi(buf); } } #ifdef G_OS_WIN32 else if (strncmp(buf, "window", 6) == 0) { HWND hwnd = (HWND) gdk_win32_window_get_handle(gtk_widget_get_window(window)); socket_fd_write(sock, (gchar *)&hwnd, sizeof(hwnd)); } #endif } if (popup) { #ifdef GDK_WINDOWING_X11 GdkWindow *x11_window = gtk_widget_get_window(window); /* Set the proper interaction time on the window. This seems necessary to make * gtk_window_present() really bring the main window into the foreground on some * window managers like Gnome's metacity. * Code taken from Gedit. */ if (GDK_IS_X11_WINDOW(x11_window)) { gdk_x11_window_set_user_time(x11_window, gdk_x11_get_server_time(x11_window)); } #endif gtk_window_present(GTK_WINDOW(window)); #ifdef G_OS_WIN32 gdk_window_show(gtk_widget_get_window(window)); #endif } socket_fd_close(sock); return TRUE; } static gint socket_fd_gets(gint fd, gchar *buf, gint len) { gchar *newline, *bp = buf; gint n; if (--len < 1) return -1; do { if ((n = socket_fd_recv(fd, bp, len, MSG_PEEK)) <= 0) return -1; if ((newline = memchr(bp, '\n', n)) != NULL) n = newline - bp + 1; if ((n = socket_fd_read(fd, bp, n)) < 0) return -1; bp += n; len -= n; } while (! newline && len); *bp = '\0'; return bp - buf; } static gint socket_fd_recv(gint fd, gchar *buf, gint len, gint flags) { if (socket_fd_check_io(fd, G_IO_IN) < 0) return -1; return recv(fd, buf, len, flags); } static gint socket_fd_read(gint fd, gchar *buf, gint len) { if (socket_fd_check_io(fd, G_IO_IN) < 0) return -1; #ifdef G_OS_WIN32 return recv(fd, buf, len, 0); #else return read(fd, buf, len); #endif } static gint socket_fd_check_io(gint fd, GIOCondition cond) { struct timeval timeout; fd_set fds; #ifdef G_OS_UNIX gint flags; #endif timeout.tv_sec = 60; timeout.tv_usec = 0; #ifdef G_OS_UNIX /* checking for non-blocking mode */ flags = fcntl(fd, F_GETFL, 0); if (flags < 0) { log_error("fcntl() failed", errno); return 0; } if ((flags & O_NONBLOCK) != 0) return 0; #endif FD_ZERO(&fds); #ifdef G_OS_WIN32 FD_SET((SOCKET)fd, &fds); #else FD_SET(fd, &fds); #endif if (cond == G_IO_IN) { select(fd + 1, &fds, NULL, NULL, &timeout); } else { select(fd + 1, NULL, &fds, NULL, &timeout); } if (FD_ISSET(fd, &fds)) { return 0; } else { geany_debug("Socket IO timeout"); return -1; } } static gint socket_fd_write_all(gint fd, const gchar *buf, gint len) { gint n, wrlen = 0; while (len) { n = socket_fd_write(fd, buf, len); if (n <= 0) return -1; len -= n; wrlen += n; buf += n; } return wrlen; } gint socket_fd_write(gint fd, const gchar *buf, gint len) { if (socket_fd_check_io(fd, G_IO_OUT) < 0) return -1; #ifdef G_OS_WIN32 return send(fd, buf, len, 0); #else return write(fd, buf, len); #endif } #endif geany-2.0/src/geanyobject.c0000644000175000017500000001755414514252267012650 00000000000000/* * geanyobject.c - this file is part of Geany, a fast and lightweight IDE * * Copyright 2007 The Geany contributors * * This program 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; either version 2 of the License, or * (at your option) any later version. * * This program 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /* A GObject used for connecting and emitting signals when certain events happen, * e.g. opening a document. * Mainly used for plugins - see the API docs. * * Core-only signals: * * signal void save_settings(GObject *obj, GKeyFile *keyfile, gpointer user_data); * Emitted just before saving main keyfile settings. * signal void load_settings(GObject *obj, GKeyFile *keyfile, gpointer user_data); * Emitted just after loading main keyfile settings. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include "geanyobject.h" /* extern in geany.h */ GObject *geany_object; static guint geany_object_signals[GCB_MAX] = { 0 }; typedef struct _GeanyObjectPrivate GeanyObjectPrivate; struct _GeanyObjectPrivate { /* to avoid warnings (g_type_class_add_private: assertion `private_size > 0' failed) */ gchar dummy; }; /** @gironly * Get the GObject-derived GType for GeanyObject * * @return GeanyObject type */ GEANY_API_SYMBOL GType geany_object_get_type(void); G_DEFINE_TYPE(GeanyObject, geany_object, G_TYPE_OBJECT) static gboolean boolean_handled_accumulator(GSignalInvocationHint *ihint, GValue *return_accu, const GValue *handler_return, gpointer dummy) { gboolean continue_emission, signal_handled; signal_handled = g_value_get_boolean(handler_return); g_value_set_boolean(return_accu, signal_handled); continue_emission = !signal_handled; return continue_emission; } static void create_signals(GObjectClass *g_object_class) { /* Document signals */ geany_object_signals[GCB_DOCUMENT_NEW] = g_signal_new ( "document-new", G_OBJECT_CLASS_TYPE (g_object_class), G_SIGNAL_RUN_FIRST, 0, NULL, NULL, g_cclosure_marshal_VOID__BOXED, G_TYPE_NONE, 1, GEANY_TYPE_DOCUMENT); geany_object_signals[GCB_DOCUMENT_OPEN] = g_signal_new ( "document-open", G_OBJECT_CLASS_TYPE (g_object_class), G_SIGNAL_RUN_FIRST, 0, NULL, NULL, g_cclosure_marshal_VOID__BOXED, G_TYPE_NONE, 1, GEANY_TYPE_DOCUMENT); geany_object_signals[GCB_DOCUMENT_RELOAD] = g_signal_new ( "document-reload", G_OBJECT_CLASS_TYPE (g_object_class), G_SIGNAL_RUN_FIRST, 0, NULL, NULL, g_cclosure_marshal_VOID__BOXED, G_TYPE_NONE, 1, GEANY_TYPE_DOCUMENT); geany_object_signals[GCB_DOCUMENT_BEFORE_SAVE] = g_signal_new ( "document-before-save", G_OBJECT_CLASS_TYPE (g_object_class), G_SIGNAL_RUN_FIRST, 0, NULL, NULL, g_cclosure_marshal_VOID__BOXED, G_TYPE_NONE, 1, GEANY_TYPE_DOCUMENT); geany_object_signals[GCB_DOCUMENT_SAVE] = g_signal_new ( "document-save", G_OBJECT_CLASS_TYPE (g_object_class), G_SIGNAL_RUN_FIRST, 0, NULL, NULL, g_cclosure_marshal_VOID__BOXED, G_TYPE_NONE, 1, GEANY_TYPE_DOCUMENT); geany_object_signals[GCB_DOCUMENT_FILETYPE_SET] = g_signal_new ( "document-filetype-set", G_OBJECT_CLASS_TYPE (g_object_class), G_SIGNAL_RUN_FIRST, 0, NULL, NULL, NULL, G_TYPE_NONE, 2, GEANY_TYPE_DOCUMENT, GEANY_TYPE_FILETYPE); geany_object_signals[GCB_DOCUMENT_ACTIVATE] = g_signal_new ( "document-activate", G_OBJECT_CLASS_TYPE (g_object_class), G_SIGNAL_RUN_FIRST, 0, NULL, NULL, g_cclosure_marshal_VOID__BOXED, G_TYPE_NONE, 1, GEANY_TYPE_DOCUMENT); geany_object_signals[GCB_DOCUMENT_CLOSE] = g_signal_new ( "document-close", G_OBJECT_CLASS_TYPE (g_object_class), G_SIGNAL_RUN_FIRST, 0, NULL, NULL, g_cclosure_marshal_VOID__BOXED, G_TYPE_NONE, 1, GEANY_TYPE_DOCUMENT); /* Project signals */ geany_object_signals[GCB_PROJECT_OPEN] = g_signal_new ( "project-open", G_OBJECT_CLASS_TYPE (g_object_class), G_SIGNAL_RUN_FIRST, 0, NULL, NULL, g_cclosure_marshal_VOID__BOXED, G_TYPE_NONE, 1, G_TYPE_KEY_FILE); geany_object_signals[GCB_PROJECT_SAVE] = g_signal_new ( "project-save", G_OBJECT_CLASS_TYPE (g_object_class), G_SIGNAL_RUN_FIRST, 0, NULL, NULL, g_cclosure_marshal_VOID__BOXED, G_TYPE_NONE, 1, G_TYPE_KEY_FILE); geany_object_signals[GCB_PROJECT_CLOSE] = g_signal_new ( "project-close", G_OBJECT_CLASS_TYPE (g_object_class), G_SIGNAL_RUN_FIRST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); geany_object_signals[GCB_PROJECT_BEFORE_CLOSE] = g_signal_new ( "project-before-close", G_OBJECT_CLASS_TYPE (g_object_class), G_SIGNAL_RUN_FIRST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); geany_object_signals[GCB_PROJECT_DIALOG_OPEN] = g_signal_new ( "project-dialog-open", G_OBJECT_CLASS_TYPE (g_object_class), G_SIGNAL_RUN_FIRST, 0, NULL, NULL, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, GTK_TYPE_NOTEBOOK); geany_object_signals[GCB_PROJECT_DIALOG_CONFIRMED] = g_signal_new ( "project-dialog-confirmed", G_OBJECT_CLASS_TYPE (g_object_class), G_SIGNAL_RUN_FIRST, 0, NULL, NULL, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, GTK_TYPE_NOTEBOOK); geany_object_signals[GCB_PROJECT_DIALOG_CLOSE] = g_signal_new ( "project-dialog-close", G_OBJECT_CLASS_TYPE (g_object_class), G_SIGNAL_RUN_FIRST, 0, NULL, NULL, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, GTK_TYPE_NOTEBOOK); /* Editor signals */ geany_object_signals[GCB_UPDATE_EDITOR_MENU] = g_signal_new ( "update-editor-menu", G_OBJECT_CLASS_TYPE (g_object_class), G_SIGNAL_RUN_FIRST, 0, NULL, NULL, NULL, G_TYPE_NONE, 3, G_TYPE_STRING, G_TYPE_INT, GEANY_TYPE_DOCUMENT); geany_object_signals[GCB_EDITOR_NOTIFY] = g_signal_new ( "editor-notify", G_OBJECT_CLASS_TYPE (g_object_class), G_SIGNAL_RUN_LAST, 0, boolean_handled_accumulator, NULL, NULL, G_TYPE_BOOLEAN, 2, GEANY_TYPE_EDITOR, SCINTILLA_TYPE_NOTIFICATION); /* General signals */ geany_object_signals[GCB_GEANY_STARTUP_COMPLETE] = g_signal_new ( "geany-startup-complete", G_OBJECT_CLASS_TYPE (g_object_class), G_SIGNAL_RUN_FIRST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); geany_object_signals[GCB_BUILD_START] = g_signal_new ( "build-start", G_OBJECT_CLASS_TYPE (g_object_class), G_SIGNAL_RUN_FIRST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); /* Core-only signals */ geany_object_signals[GCB_SAVE_SETTINGS] = g_signal_new ( "save-settings", G_OBJECT_CLASS_TYPE (g_object_class), G_SIGNAL_RUN_FIRST, 0, NULL, NULL, g_cclosure_marshal_VOID__BOXED, G_TYPE_NONE, 1, G_TYPE_KEY_FILE); geany_object_signals[GCB_LOAD_SETTINGS] = g_signal_new ( "load-settings", G_OBJECT_CLASS_TYPE (g_object_class), G_SIGNAL_RUN_FIRST, 0, NULL, NULL, g_cclosure_marshal_VOID__BOXED, G_TYPE_NONE, 1, G_TYPE_KEY_FILE); /* Key press signal */ geany_object_signals[GCB_KEY_PRESS_NOTIFY] = g_signal_new ( "key-press", G_OBJECT_CLASS_TYPE (g_object_class), G_SIGNAL_RUN_LAST, 0, boolean_handled_accumulator, NULL, NULL, G_TYPE_BOOLEAN, 1, GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE); } static void geany_object_class_init(GeanyObjectClass *klass) { GObjectClass *g_object_class; g_object_class = G_OBJECT_CLASS(klass); g_type_class_add_private(klass, sizeof(GeanyObjectPrivate)); create_signals(g_object_class); } static void geany_object_init(GeanyObject *self) { /* nothing to do */ } GObject *geany_object_new(void) { return g_object_new(GEANY_OBJECT_TYPE, NULL); } geany-2.0/src/document.c0000644000175000017500000033226514514252267012173 00000000000000/* * document.c - this file is part of Geany, a fast and lightweight IDE * * Copyright 2005 The Geany contributors * * This program 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; either version 2 of the License, or * (at your option) any later version. * * This program 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /* * Document related actions: new, save, open, etc. * Also Scintilla search actions. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include "document.h" #include "app.h" #include "callbacks.h" /* for ignore_callback */ #include "dialogs.h" #include "documentprivate.h" #include "encodings.h" #include "encodingsprivate.h" #include "filetypesprivate.h" #include "geany.h" /* FIXME: why is this needed for DOC_FILENAME()? should come from documentprivate.h/document.h */ #include "geanyobject.h" #include "geanywraplabel.h" #include "highlighting.h" #include "main.h" #include "msgwindow.h" #include "navqueue.h" #include "notebook.h" #include "project.h" #include "sciwrappers.h" #include "sidebar.h" #include "support.h" #include "symbols.h" #include "ui_utils.h" #include "utils.h" #include "vte.h" #include "win32.h" #ifdef HAVE_SYS_TIME_H # include #endif #include #include #include #include #ifdef HAVE_SYS_TYPES_H # include #endif #include /* gstdio.h also includes sys/stat.h */ #include /* uncomment to use GIO based file monitoring, though it is not completely stable yet */ /*#define USE_GIO_FILEMON 1*/ #include #include #include #define USE_GIO_FILE_OPERATIONS (!file_prefs.use_safe_file_saving && file_prefs.use_gio_unsafe_file_saving) GeanyFilePrefs file_prefs; GPtrArray *documents_array = NULL; /* an undo action, also used for redo actions */ typedef struct { GTrashStack *next; /* pointer to the next stack element(required for the GTrashStack) */ guint type; /* to identify the action */ gpointer *data; /* the old value (before the change), in case of a redo action * it contains the new value */ } undo_action; /* Custom document info bar response IDs */ enum { RESPONSE_DOCUMENT_RELOAD = 1, RESPONSE_DOCUMENT_SAVE, }; static guint show_tab_idle = 0; static guint doc_id_counter = 0; static void document_undo_clear_stack(GTrashStack **stack); static void document_undo_clear(GeanyDocument *doc); static void document_undo_add_internal(GeanyDocument *doc, guint type, gpointer data); static void document_redo_add(GeanyDocument *doc, guint type, gpointer data); static gboolean remove_page(guint page_num); static GtkWidget* document_show_message(GeanyDocument *doc, GtkMessageType msgtype, void (*response_cb)(GtkWidget *info_bar, gint response_id, GeanyDocument *doc), const gchar *btn_1, GtkResponseType response_1, const gchar *btn_2, GtkResponseType response_2, const gchar *btn_3, GtkResponseType response_3, const gchar *extra_text, const gchar *format, ...) G_GNUC_PRINTF(11, 12); /** * Finds a document whose @c real_path field matches the given filename. * * @param realname The filename to search, which should be identical to the * string returned by @c utils_get_real_path(). * * @return @transfer{none} @nullable The matching document, or @c NULL. * @note This is only really useful when passing a @c TMSourceFile::file_name. * @see GeanyDocument::real_path. * @see document_find_by_filename(). * * @since 0.15 **/ GEANY_API_SYMBOL GeanyDocument* document_find_by_real_path(const gchar *realname) { guint i; if (! realname) return NULL; /* file doesn't exist on disk */ for (i = 0; i < documents_array->len; i++) { GeanyDocument *doc = documents[i]; if (! doc->is_valid || ! doc->real_path) continue; if (utils_filenamecmp(realname, doc->real_path) == 0) { return doc; } } return NULL; } /* dereference symlinks, /../ junk in path and return locale encoding */ static gchar *get_real_path_from_utf8(const gchar *utf8_filename) { gchar *locale_name = utils_get_locale_from_utf8(utf8_filename); gchar *realname = utils_get_real_path(locale_name); g_free(locale_name); return realname; } /** * Finds a document with the given filename. * This matches either an exact GeanyDocument::file_name string, or variant * filenames with relative elements in the path (e.g. @c "/dir/..//name" will * match @c "/name"). * * @param utf8_filename The filename to search (in UTF-8 encoding). * * @return @transfer{none} @nullable The matching document, or @c NULL. * @see document_find_by_real_path(). **/ GEANY_API_SYMBOL GeanyDocument *document_find_by_filename(const gchar *utf8_filename) { guint i; GeanyDocument *doc; gchar *realname; g_return_val_if_fail(utf8_filename != NULL, NULL); /* First search GeanyDocument::file_name, so we can find documents with a * filename set but not saved on disk, like vcdiff produces */ for (i = 0; i < documents_array->len; i++) { doc = documents[i]; if (! doc->is_valid || doc->file_name == NULL) continue; if (utils_filenamecmp(utf8_filename, doc->file_name) == 0) { return doc; } } /* Now try matching based on the realpath(), which is unique per file on disk */ realname = get_real_path_from_utf8(utf8_filename); doc = document_find_by_real_path(realname); g_free(realname); return doc; } /* returns the document which has sci, or NULL. */ GeanyDocument *document_find_by_sci(ScintillaObject *sci) { guint i; g_return_val_if_fail(sci != NULL, NULL); for (i = 0; i < documents_array->len; i++) { if (documents[i]->is_valid && documents[i]->editor->sci == sci) return documents[i]; } return NULL; } /** Lookup an old document by its ID. * Useful when the corresponding document may have been closed since the * ID was retrieved. * @param id The ID of the document to find * @return @transfer{none} @c NULL if the document is no longer open. * * Example: * @code * static guint id; * GeanyDocument *doc = ...; * id = doc->id; // store ID * ... * // time passes - the document may have been closed by now * GeanyDocument *doc = document_find_by_id(id); * gboolean still_open = (doc != NULL); * @endcode * @since 1.25. */ GEANY_API_SYMBOL GeanyDocument *document_find_by_id(guint id) { guint i; if (!id) return NULL; foreach_document(i) { if (documents[i]->id == id) return documents[i]; } return NULL; } /* gets the widget the main_widgets.notebook consider is its child for this document */ static GtkWidget *document_get_notebook_child(GeanyDocument *doc) { GtkWidget *parent; GtkWidget *child; g_return_val_if_fail(doc != NULL, NULL); child = GTK_WIDGET(doc->editor->sci); parent = gtk_widget_get_parent(child); /* search for the direct notebook child, mirroring document_get_from_page() */ while (parent && ! GTK_IS_NOTEBOOK(parent)) { child = parent; parent = gtk_widget_get_parent(child); } return child; } /** Gets the notebook page index for a document. * @param doc The document. * @return The index. * @since 0.19 */ GEANY_API_SYMBOL gint document_get_notebook_page(GeanyDocument *doc) { GtkWidget *child = document_get_notebook_child(doc); return gtk_notebook_page_num(GTK_NOTEBOOK(main_widgets.notebook), child); } /* * Recursively searches a containers children until it finds a * Scintilla widget, or NULL if one was not found. */ static ScintillaObject *locate_sci_in_container(GtkWidget *container) { ScintillaObject *sci = NULL; GList *children, *iter; g_return_val_if_fail(GTK_IS_CONTAINER(container), NULL); children = gtk_container_get_children(GTK_CONTAINER(container)); for (iter = children; iter != NULL; iter = g_list_next(iter)) { if (IS_SCINTILLA(iter->data)) { sci = SCINTILLA(iter->data); break; } else if (GTK_IS_CONTAINER(iter->data)) { sci = locate_sci_in_container(iter->data); if (IS_SCINTILLA(sci)) break; sci = NULL; } } g_list_free(children); return sci; } /* Finds the document for the given notebook page widget */ GeanyDocument *document_get_from_notebook_child(GtkWidget *page) { ScintillaObject *sci; g_return_val_if_fail(GTK_IS_BOX(page), NULL); sci = locate_sci_in_container(page); g_return_val_if_fail(IS_SCINTILLA(sci), NULL); return document_find_by_sci(sci); } /** * Finds the document for the given notebook page @a page_num. * * @param page_num The notebook page number to search. * * @return @transfer{none} @nullable The corresponding document for the given notebook page, or @c NULL. **/ GEANY_API_SYMBOL GeanyDocument *document_get_from_page(guint page_num) { GtkWidget *parent; if (page_num >= documents_array->len) return NULL; parent = gtk_notebook_get_nth_page(GTK_NOTEBOOK(main_widgets.notebook), page_num); return document_get_from_notebook_child(parent); } /** * Finds the current document. * * @return @transfer{none} @nullable A pointer to the current document or @c NULL if there are no opened documents. **/ GEANY_API_SYMBOL GeanyDocument *document_get_current(void) { gint cur_page = gtk_notebook_get_current_page(GTK_NOTEBOOK(main_widgets.notebook)); if (cur_page == -1) return NULL; else return document_get_from_page((guint) cur_page); } void document_init_doclist(void) { documents_array = g_ptr_array_new(); } void document_finalize(void) { guint i; for (i = 0; i < documents_array->len; i++) g_free(documents[i]); g_ptr_array_free(documents_array, TRUE); } /** * Returns the last part of the filename of the given GeanyDocument. The result is also * truncated to a maximum of @a length characters in case the filename is very long. * * @param doc The document to use. * @param length The length of the resulting string or -1 to use a default value. * * @return The ellipsized last part of the filename of @a doc, should be freed when no * longer needed. * * @since 0.17 */ /* TODO make more use of this */ GEANY_API_SYMBOL gchar *document_get_basename_for_display(GeanyDocument *doc, gint length) { gchar *base_name, *short_name; g_return_val_if_fail(doc != NULL, NULL); if (length < 0) length = 30; base_name = g_path_get_basename(DOC_FILENAME(doc)); short_name = utils_str_middle_truncate(base_name, (guint)length); g_free(base_name); return short_name; } void document_update_tab_label(GeanyDocument *doc) { gchar *short_name; GtkWidget *parent; g_return_if_fail(doc != NULL); short_name = document_get_basename_for_display(doc, interface_prefs.tab_label_len); /* we need to use the event box for the tooltip, labels don't get the necessary events */ parent = gtk_widget_get_parent(doc->priv->tab_label); parent = gtk_widget_get_parent(parent); gtk_label_set_text(GTK_LABEL(doc->priv->tab_label), short_name); gtk_widget_set_tooltip_text(parent, DOC_FILENAME(doc)); g_free(short_name); } /** * Updates the tab labels, the status bar, the window title and some save-sensitive buttons * according to the document's save state. * This is called by Geany mostly when opening or saving files. * * @param doc The document to use. * @param changed Whether the document state should indicate changes have been made. **/ GEANY_API_SYMBOL void document_set_text_changed(GeanyDocument *doc, gboolean changed) { g_return_if_fail(doc != NULL); doc->changed = changed; if (! main_status.quitting) { ui_update_tab_status(doc); ui_save_buttons_toggle(changed); ui_set_window_title(doc); ui_update_statusbar(doc, -1); } } /* returns the next free place in the document list, * or -1 if the documents_array is full */ static gint document_get_new_idx(void) { guint i; for (i = 0; i < documents_array->len; i++) { if (documents[i]->editor == NULL) { return (gint) i; } } return -1; } static void queue_colourise(GeanyDocument *doc) { if (doc->priv->colourise_needed) return; /* Colourise the editor before it is next drawn */ doc->priv->colourise_needed = TRUE; /* If the editor doesn't need drawing (e.g. after saving the current * document), we need to force a redraw, so the expose event is triggered. * This ensures we don't start colourising before all documents are opened/saved, * only once the editor is drawn. */ gtk_widget_queue_draw(GTK_WIDGET(doc->editor->sci)); } #ifdef USE_GIO_FILEMON static void monitor_file_changed_cb(G_GNUC_UNUSED GFileMonitor *monitor, G_GNUC_UNUSED GFile *file, G_GNUC_UNUSED GFile *other_file, GFileMonitorEvent event, GeanyDocument *doc) { g_return_if_fail(doc != NULL); if (file_prefs.disk_check_timeout == 0) return; geany_debug("%s: event: %d previous file status: %d", G_STRFUNC, event, doc->priv->file_disk_status); switch (event) { case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT: { if (doc->priv->file_disk_status == FILE_IGNORE) doc->priv->file_disk_status = FILE_OK; else doc->priv->file_disk_status = FILE_CHANGED; g_message("%s: FILE_CHANGED", G_STRFUNC); break; } case G_FILE_MONITOR_EVENT_DELETED: { doc->priv->file_disk_status = FILE_CHANGED; g_message("%s: FILE_MISSING", G_STRFUNC); break; } default: break; } if (doc->priv->file_disk_status != FILE_OK) { ui_update_tab_status(doc); } } #endif static void document_stop_file_monitoring(GeanyDocument *doc) { g_return_if_fail(doc != NULL); if (doc->priv->monitor != NULL) { g_object_unref(doc->priv->monitor); doc->priv->monitor = NULL; } } static void monitor_file_setup(GeanyDocument *doc) { g_return_if_fail(doc != NULL); /* Disable file monitoring completely for remote files (i.e. remote GIO files) as GFileMonitor * doesn't work at all for remote files and legacy polling is too slow. */ if (! doc->priv->is_remote) { #ifdef USE_GIO_FILEMON gchar *locale_filename; /* stop any previous monitoring */ document_stop_file_monitoring(doc); locale_filename = utils_get_locale_from_utf8(doc->file_name); if (locale_filename != NULL && g_file_test(locale_filename, G_FILE_TEST_EXISTS)) { /* get a file monitor and connect to the 'changed' signal */ GFile *file = g_file_new_for_path(locale_filename); doc->priv->monitor = g_file_monitor_file(file, G_FILE_MONITOR_NONE, NULL, NULL); g_signal_connect(doc->priv->monitor, "changed", G_CALLBACK(monitor_file_changed_cb), doc); /* we set the rate limit according to the GUI pref but it's most probably not used */ g_file_monitor_set_rate_limit(doc->priv->monitor, file_prefs.disk_check_timeout * 1000); g_object_unref(file); } g_free(locale_filename); #endif } doc->priv->file_disk_status = FILE_OK; } void document_try_focus(GeanyDocument *doc, GtkWidget *source_widget) { /* doc might not be valid e.g. if user closed a tab whilst Geany is opening files */ if (DOC_VALID(doc)) { GtkWidget *sci = GTK_WIDGET(doc->editor->sci); GtkWidget *focusw = gtk_window_get_focus(GTK_WINDOW(main_widgets.window)); if (source_widget == NULL) source_widget = doc->priv->tag_tree; if (focusw == source_widget) gtk_widget_grab_focus(sci); } } /* Creates a new document and editor, adding a tab in the notebook. * @return The created document */ static GeanyDocument *document_create(const gchar *utf8_filename) { GeanyDocument *doc; gint new_idx; gint cur_pages = gtk_notebook_get_n_pages(GTK_NOTEBOOK(main_widgets.notebook)); if (cur_pages == 1) { doc = document_get_current(); /* remove the empty document first */ if (doc != NULL && doc->file_name == NULL && ! doc->changed) /* prevent immediately opening another new doc with * new_document_after_close pref */ remove_page(0); } new_idx = document_get_new_idx(); if (new_idx == -1) /* expand the array, no free places */ { doc = g_new0(GeanyDocument, 1); new_idx = documents_array->len; g_ptr_array_add(documents_array, doc); } doc = documents[new_idx]; /* initialize default document settings */ doc->priv = g_new0(GeanyDocumentPrivate, 1); doc->priv->tag_filter = g_strdup(""); doc->priv->symbols_group_by_type = TRUE; doc->id = ++doc_id_counter; doc->index = new_idx; doc->file_name = g_strdup(utf8_filename); doc->editor = editor_create(doc); #ifndef USE_GIO_FILEMON doc->priv->last_check = time(NULL); #endif g_datalist_init(&doc->priv->data); sidebar_openfiles_add(doc); /* sets doc->iter */ notebook_new_tab(doc); /* select document in sidebar */ { GtkTreeSelection *sel; sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(tv.tree_openfiles)); gtk_tree_selection_select_iter(sel, &doc->priv->iter); } ui_document_buttons_update(); doc->is_valid = TRUE; /* do this last to prevent UI updating with NULL items. */ return doc; } /** * Closes the given document. * * @param doc The document to remove. * * @return @c TRUE if the document was actually removed or @c FALSE otherwise. * * @since 0.15 **/ GEANY_API_SYMBOL gboolean document_close(GeanyDocument *doc) { g_return_val_if_fail(doc, FALSE); return document_remove_page(document_get_notebook_page(doc)); } /* Call document_remove_page() instead, this is only needed for document_create() * to prevent re-opening a new document when the last document is closed (if enabled). */ static gboolean remove_page(guint page_num) { GeanyDocument *doc = document_get_from_page(page_num); g_return_val_if_fail(doc != NULL, FALSE); /* if we're closing all, document_account_for_unsaved() has been called already, no need to ask again. */ if (! main_status.closing_all && doc->changed && ! dialogs_show_unsaved_file(doc)) return FALSE; /* tell any plugins that the document is about to be closed */ g_signal_emit_by_name(geany_object, "document-close", doc); /* Checking real_path makes it likely the file exists on disk */ if (! main_status.closing_all && doc->real_path != NULL) ui_add_recent_document(doc); g_datalist_clear(&doc->priv->data); doc->is_valid = FALSE; doc->id = 0; if (main_status.quitting) { /* we need to destroy the ScintillaWidget so our handlers on it are * disconnected before we free any data they may use (like the editor). * when not quitting, this is handled by removing the notebook page. */ gtk_notebook_remove_page(GTK_NOTEBOOK(main_widgets.notebook), page_num); } else { notebook_remove_page(page_num); sidebar_remove_document(doc); navqueue_remove_file(doc->file_name); msgwin_status_add(_("File %s closed."), DOC_FILENAME(doc)); } g_free(doc->encoding); g_free(doc->priv->saved_encoding.encoding); g_free(doc->priv->tag_filter); g_free(doc->file_name); g_free(doc->real_path); if (doc->tm_file) { tm_workspace_remove_source_file(doc->tm_file); tm_source_file_free(doc->tm_file); } if (doc->priv->tag_tree) gtk_widget_destroy(doc->priv->tag_tree); editor_destroy(doc->editor); doc->editor = NULL; /* needs to be NULL for document_undo_clear() call below */ document_stop_file_monitoring(doc); document_undo_clear(doc); g_free(doc->priv); /* reset document settings to defaults for re-use */ memset(doc, 0, sizeof(GeanyDocument)); if (gtk_notebook_get_n_pages(GTK_NOTEBOOK(main_widgets.notebook)) == 0) { sidebar_update_tag_list(NULL, FALSE); ui_set_window_title(NULL); ui_save_buttons_toggle(FALSE); ui_update_popup_reundo_items(NULL); ui_document_buttons_update(); build_menu_update(NULL); } return TRUE; } /** * Removes the given notebook tab at @a page_num and clears all related information * in the document list. * * @param page_num The notebook page number to remove. * * @return @c TRUE if the document was actually removed or @c FALSE otherwise. **/ GEANY_API_SYMBOL gboolean document_remove_page(guint page_num) { gboolean done = remove_page(page_num); if (done && ui_prefs.new_document_after_close) document_new_file_if_non_open(); return done; } /* used to keep a record of the unchanged document state encoding */ static void store_saved_encoding(GeanyDocument *doc) { g_free(doc->priv->saved_encoding.encoding); doc->priv->saved_encoding.encoding = g_strdup(doc->encoding); doc->priv->saved_encoding.has_bom = doc->has_bom; } /* Opens a new empty document only if there are no other documents open */ GeanyDocument *document_new_file_if_non_open(void) { if (gtk_notebook_get_n_pages(GTK_NOTEBOOK(main_widgets.notebook)) == 0) return document_new_file(NULL, NULL, NULL); return NULL; } /** * Creates a new document. * Line endings in @a text will be converted to the default setting. * Afterwards, the @c "document-new" signal is emitted for plugins. * * @param utf8_filename @nullable The file name in UTF-8 encoding, or @c NULL to open a file as "untitled". * @param ft @nullable The filetype to set or @c NULL to detect it from @a filename if not @c NULL. * @param text @nullable The initial content of the file (in UTF-8 encoding), or @c NULL. * * @return @transfer{none} The new document. **/ GEANY_API_SYMBOL GeanyDocument *document_new_file(const gchar *utf8_filename, GeanyFiletype *ft, const gchar *text) { GeanyDocument *doc; if (utf8_filename && g_path_is_absolute(utf8_filename)) { gchar *tmp; tmp = utils_strdupa(utf8_filename); /* work around const */ utils_tidy_path(tmp); utf8_filename = tmp; } doc = document_create(utf8_filename); g_assert(doc != NULL); sci_set_undo_collection(doc->editor->sci, FALSE); /* avoid creation of an undo action */ if (text) { GString *template = g_string_new(text); utils_ensure_same_eol_characters(template, file_prefs.default_eol_character); sci_set_text(doc->editor->sci, template->str); g_string_free(template, TRUE); } else sci_clear_all(doc->editor->sci); sci_set_eol_mode(doc->editor->sci, file_prefs.default_eol_character); sci_set_undo_collection(doc->editor->sci, TRUE); sci_empty_undo_buffer(doc->editor->sci); doc->encoding = g_strdup(encodings[file_prefs.default_new_encoding].charset); /* store the opened encoding for undo/redo */ store_saved_encoding(doc); if (ft == NULL && utf8_filename != NULL) /* guess the filetype from the filename if one is given */ ft = filetypes_detect_from_document(doc); document_set_filetype(doc, ft); /* also re-parses tags */ ui_set_window_title(doc); build_menu_update(doc); document_set_text_changed(doc, FALSE); ui_document_show_hide(doc); /* update the document menu */ sci_set_line_numbers(doc->editor->sci, editor_prefs.show_linenumber_margin); /* bring it in front, jump to the start and grab the focus */ editor_goto_pos(doc->editor, 0, FALSE); #ifdef USE_GIO_FILEMON monitor_file_setup(doc); #else doc->priv->mtime = 0; #endif /* "the" SCI signal (connect after initial setup(i.e. adding text)) */ g_signal_connect(doc->editor->sci, "sci-notify", G_CALLBACK(editor_sci_notify_cb), doc->editor); g_signal_emit_by_name(geany_object, "document-new", doc); msgwin_status_add(_("New file \"%s\" opened."), DOC_FILENAME(doc)); return doc; } /** * Opens a document specified by @a locale_filename. * Afterwards, the @c "document-open" signal is emitted for plugins. * * @param locale_filename The filename of the document to load, in locale encoding. * @param readonly Whether to open the document in read-only mode. * @param ft @nullable The filetype for the document or @c NULL to auto-detect the filetype. * @param forced_enc @nullable The file encoding to use or @c NULL to auto-detect the file encoding. * * @return @transfer{none} @nullable The document opened or @c NULL. **/ GEANY_API_SYMBOL GeanyDocument *document_open_file(const gchar *locale_filename, gboolean readonly, GeanyFiletype *ft, const gchar *forced_enc) { return document_open_file_full(NULL, locale_filename, 0, readonly, ft, forced_enc); } typedef struct { gchar *data; /* null-terminated file data */ gsize len; /* string length of data */ gchar *enc; gboolean bom; time_t mtime; /* modification time, read by stat::st_mtime */ gboolean readonly; } FileData; static gboolean get_mtime(const gchar *locale_filename, time_t *time) { GError *error = NULL; const gchar *err_msg = NULL; if (USE_GIO_FILE_OPERATIONS) { GFile *file = g_file_new_for_path(locale_filename); GFileInfo *info = g_file_query_info(file, G_FILE_ATTRIBUTE_TIME_MODIFIED, G_FILE_QUERY_INFO_NONE, NULL, &error); if (info) { GTimeVal timeval; g_file_info_get_modification_time(info, &timeval); g_object_unref(info); *time = timeval.tv_sec; } else if (error) err_msg = error->message; g_object_unref(file); } else { GStatBuf st; if (g_stat(locale_filename, &st) == 0) *time = st.st_mtime; else err_msg = g_strerror(errno); } if (err_msg) { gchar *utf8_filename = utils_get_utf8_from_locale(locale_filename); ui_set_statusbar(TRUE, _("Could not open file %s (%s)"), utf8_filename, err_msg); g_free(utf8_filename); } if (error) g_error_free(error); return err_msg == NULL; } /* loads textfile data, verifies and converts to forced_enc or UTF-8. Also handles BOM. */ static gboolean load_text_file(const gchar *locale_filename, const gchar *display_filename, FileData *filedata, const gchar *forced_enc) { GError *err = NULL; filedata->data = NULL; filedata->len = 0; filedata->enc = NULL; filedata->bom = FALSE; filedata->readonly = FALSE; if (!get_mtime(locale_filename, &filedata->mtime)) return FALSE; if (USE_GIO_FILE_OPERATIONS) { GFile *file = g_file_new_for_path(locale_filename); g_file_load_contents(file, NULL, &filedata->data, &filedata->len, NULL, &err); g_object_unref(file); } else g_file_get_contents(locale_filename, &filedata->data, &filedata->len, &err); if (err) { ui_set_statusbar(TRUE, "%s", err->message); g_error_free(err); return FALSE; } if (! encodings_convert_to_utf8_auto(&filedata->data, &filedata->len, forced_enc, &filedata->enc, &filedata->bom, &filedata->readonly)) { if (forced_enc) { ui_set_statusbar(TRUE, _("The file \"%s\" is not valid %s."), display_filename, forced_enc); } else { ui_set_statusbar(TRUE, _("The file \"%s\" does not look like a text file or the file encoding is not supported."), display_filename); } g_free(filedata->data); return FALSE; } if (filedata->readonly) { const gchar *warn_msg = _( "The file \"%s\" could not be opened properly and has been truncated. " \ "This can occur if the file contains a NULL byte. " \ "Be aware that saving it can cause data loss.\nThe file was set to read-only."); if (main_status.main_window_realized) dialogs_show_msgbox(GTK_MESSAGE_WARNING, warn_msg, display_filename); ui_set_statusbar(TRUE, warn_msg, display_filename); } return TRUE; } /* Sets the cursor position on opening a file. First it sets the line when cl_options.goto_line * is set, otherwise it sets the line when pos is greater than zero and finally it sets the column * if cl_options.goto_column is set. * * returns the new position which may have changed */ static gint set_cursor_position(GeanyEditor *editor, gint pos) { if (cl_options.goto_line >= 0) { /* goto line which was specified on command line and then undefine the line */ sci_goto_line(editor->sci, cl_options.goto_line - 1, TRUE); editor->scroll_percent = 0.5F; cl_options.goto_line = -1; } else if (pos > 0) { sci_set_current_position(editor->sci, pos, FALSE); editor->scroll_percent = 0.5F; } if (cl_options.goto_column >= 0) { /* goto column which was specified on command line and then undefine the column */ gint new_pos = sci_get_current_position(editor->sci) + cl_options.goto_column; sci_set_current_position(editor->sci, new_pos, FALSE); editor->scroll_percent = 0.5F; cl_options.goto_column = -1; return new_pos; } return sci_get_current_position(editor->sci); } /* Count lines that start with some hard tabs then a soft tab. */ static gboolean detect_tabs_and_spaces(GeanyEditor *editor) { const GeanyIndentPrefs *iprefs = editor_get_indent_prefs(editor); ScintillaObject *sci = editor->sci; gsize count = 0; struct Sci_TextToFind ttf; gchar *soft_tab = g_strnfill((gsize)iprefs->width, ' '); gchar *regex = g_strconcat("^\t+", soft_tab, "[^ ]", NULL); g_free(soft_tab); ttf.chrg.cpMin = 0; ttf.chrg.cpMax = sci_get_length(sci); ttf.lpstrText = regex; while (1) { gint pos; pos = sci_find_text(sci, SCFIND_REGEXP, &ttf); if (pos == -1) break; /* no more matches */ count++; ttf.chrg.cpMin = ttf.chrgText.cpMax + 1; /* search after this match */ } g_free(regex); /* The 0.02 is a low weighting to ignore a few possibly accidental occurrences */ return count > sci_get_line_count(sci) * 0.02; } /* Detect the indent type based on counting the leading indent characters for each line. * Returns whether detection succeeded, and the detected type in *type_ upon success */ gboolean document_detect_indent_type(GeanyDocument *doc, GeanyIndentType *type_) { GeanyEditor *editor = doc->editor; ScintillaObject *sci = editor->sci; gint line, line_count; gsize tabs = 0, spaces = 0; if (detect_tabs_and_spaces(editor)) { *type_ = GEANY_INDENT_TYPE_BOTH; return TRUE; } line_count = sci_get_line_count(sci); for (line = 0; line < line_count; line++) { gint pos = sci_get_position_from_line(sci, line); gchar c; /* most code will have indent total <= 24, otherwise it's more likely to be * alignment than indentation */ if (sci_get_line_indentation(sci, line) > 24) continue; c = sci_get_char_at(sci, pos); if (c == '\t') tabs++; /* check for at least 2 spaces */ else if (c == ' ' && sci_get_char_at(sci, pos + 1) == ' ') spaces++; } if (spaces == 0 && tabs == 0) return FALSE; /* the factors may need to be tweaked */ if (spaces > tabs * 4) *type_ = GEANY_INDENT_TYPE_SPACES; else if (tabs > spaces * 4) *type_ = GEANY_INDENT_TYPE_TABS; else *type_ = GEANY_INDENT_TYPE_BOTH; return TRUE; } /* Detect the indent width based on counting the leading indent characters for each line. * Returns whether detection succeeded, and the detected width in *width_ upon success */ static gboolean detect_indent_width(GeanyEditor *editor, GeanyIndentType type, gint *width_) { const GeanyIndentPrefs *iprefs = editor_get_indent_prefs(editor); ScintillaObject *sci = editor->sci; gint line, line_count; gint widths[7] = { 0 }; /* width can be from 2 to 8 */ gint count, width, i; /* can't easily detect the supposed width of a tab, guess the default is OK */ if (type == GEANY_INDENT_TYPE_TABS) return FALSE; /* force 8 at detection time for tab & spaces -- anyway we don't use tabs at this point */ sci_set_tab_width(sci, 8); line_count = sci_get_line_count(sci); for (line = 0; line < line_count; line++) { gint pos = sci_get_line_indent_position(sci, line); /* We probably don't have style info yet, because we're generally called just after * the document got created, so we can't use highlighting_is_code_style(). * That's not good, but the assumption below that concerning lines start with an * asterisk (common continuation character for C/C++/Java/...) should do the trick * without removing too much legitimate lines. */ if (sci_get_char_at(sci, pos) == '*') continue; width = sci_get_line_indentation(sci, line); /* most code will have indent total <= 24, otherwise it's more likely to be * alignment than indentation */ if (width > 24) continue; /* < 2 is no indentation */ if (width < 2) continue; for (i = G_N_ELEMENTS(widths) - 1; i >= 0; i--) { if ((width % (i + 2)) == 0) widths[i]++; } } count = 0; width = iprefs->width; for (i = G_N_ELEMENTS(widths) - 1; i >= 0; i--) { /* give large indents higher weight not to be fooled by spurious indents */ if (widths[i] >= count * 1.5) { width = i + 2; count = widths[i]; } } if (count == 0) return FALSE; *width_ = width; return TRUE; } /* same as detect_indent_width() but uses editor's indent type */ gboolean document_detect_indent_width(GeanyDocument *doc, gint *width_) { return detect_indent_width(doc->editor, doc->editor->indent_type, width_); } void document_apply_indent_settings(GeanyDocument *doc) { const GeanyIndentPrefs *iprefs = editor_get_indent_prefs(NULL); GeanyIndentType type = iprefs->type; gint width = iprefs->width; if (iprefs->detect_type && document_detect_indent_type(doc, &type)) { if (type != iprefs->type) { const gchar *name = NULL; switch (type) { case GEANY_INDENT_TYPE_SPACES: name = _("Spaces"); break; case GEANY_INDENT_TYPE_TABS: name = _("Tabs"); break; case GEANY_INDENT_TYPE_BOTH: name = _("Tabs and Spaces"); break; } /* For translators: first wildcard is the indentation mode (Spaces, Tabs, Tabs * and Spaces), the second one is the filename */ ui_set_statusbar(TRUE, _("Setting %s indentation mode for %s."), name, DOC_FILENAME(doc)); } } else if (doc->file_type->indent_type > -1) type = doc->file_type->indent_type; if (iprefs->detect_width && detect_indent_width(doc->editor, type, &width)) { if (width != iprefs->width) { ui_set_statusbar(TRUE, _("Setting indentation width to %d for %s."), width, DOC_FILENAME(doc)); } } else if (doc->file_type->indent_width > -1) width = doc->file_type->indent_width; editor_set_indent(doc->editor, type, width); } void document_show_tab(GeanyDocument *doc) { if (show_tab_idle) { g_source_remove(show_tab_idle); show_tab_idle = 0; } gtk_notebook_set_current_page(GTK_NOTEBOOK(main_widgets.notebook), document_get_notebook_page(doc)); /* finally, let the editor widget grab the focus so you can start coding * right away */ document_try_focus(doc, NULL); } static gboolean show_tab_cb(gpointer data) { GeanyDocument *doc = (GeanyDocument *) data; show_tab_idle = 0; /* doc might not be valid e.g. if user closed a tab whilst Geany is opening files */ if (DOC_VALID(doc)) document_show_tab(doc); return G_SOURCE_REMOVE; } void document_show_tab_idle(GeanyDocument *doc) { if (show_tab_idle) g_source_remove(show_tab_idle); show_tab_idle = g_idle_add(show_tab_cb, doc); } /* To open a new file, set doc to NULL; filename should be locale encoded. * To reload a file, set the doc for the document to be reloaded; filename should be NULL. * pos is the cursor position, which can be overridden by --line and --column. * forced_enc can be NULL to detect the file encoding. * Returns: doc of the opened file or NULL if an error occurred. */ GeanyDocument *document_open_file_full(GeanyDocument *doc, const gchar *filename, gint pos, gboolean readonly, GeanyFiletype *ft, const gchar *forced_enc) { gint editor_mode; gboolean reload = (doc == NULL) ? FALSE : TRUE; gchar *utf8_filename = NULL; gchar *display_filename = NULL; gchar *locale_filename = NULL; GeanyFiletype *use_ft; FileData filedata; UndoReloadData *undo_reload_data; gboolean add_undo_reload_action; g_return_val_if_fail(doc == NULL || doc->is_valid, NULL); if (reload) { utf8_filename = g_strdup(doc->file_name); locale_filename = utils_get_locale_from_utf8(utf8_filename); } else { /* filename must not be NULL when opening a file */ g_return_val_if_fail(filename, NULL); #ifdef G_OS_WIN32 /* if filename is a shortcut, try to resolve it */ locale_filename = win32_get_shortcut_target(filename); #else locale_filename = g_strdup(filename); #endif /* remove relative junk */ utils_tidy_path(locale_filename); /* try to get the UTF-8 equivalent for the filename, fallback to filename if error */ utf8_filename = utils_get_utf8_from_locale(locale_filename); /* if file is already open, switch to it and go */ doc = document_find_by_filename(utf8_filename); if (doc != NULL) { ui_add_recent_document(doc); /* either add or reorder recent item */ document_check_disk_status(doc, TRUE); /* force a file changed check */ } } if (reload || doc == NULL) { /* doc possibly changed */ display_filename = utils_str_middle_truncate(utf8_filename, 100); if (! load_text_file(locale_filename, display_filename, &filedata, forced_enc)) { g_free(display_filename); g_free(utf8_filename); g_free(locale_filename); return NULL; } if (! reload) { doc = document_create(utf8_filename); g_return_val_if_fail(doc != NULL, NULL); /* really should not happen */ /* file exists on disk, set real_path */ SETPTR(doc->real_path, utils_get_real_path(locale_filename)); doc->priv->is_remote = utils_is_remote_path(locale_filename); monitor_file_setup(doc); } if (! reload || ! file_prefs.keep_edit_history_on_reload) { sci_set_undo_collection(doc->editor->sci, FALSE); /* avoid creation of an undo action */ sci_empty_undo_buffer(doc->editor->sci); undo_reload_data = NULL; } else { undo_reload_data = (UndoReloadData*) g_malloc(sizeof(UndoReloadData)); /* We will be adding a UNDO_RELOAD action to the undo stack that undoes * this reload. To do that, we keep collecting undo actions during * reloading, and at the end add an UNDO_RELOAD action that performs * all these actions in bulk. To keep track of how many undo actions * were added during this time, we compare the current undo-stack height * with its height at the end of the process. Note that g_trash_stack_height() * is O(N), which is a little ugly, but this seems like the most maintainable * option. */ undo_reload_data->actions_count = g_trash_stack_height(&doc->priv->undo_actions); /* We use add_undo_reload_action to track any changes to the document that * require adding an undo action to revert the reload, but that do not * generate an undo action themselves. */ add_undo_reload_action = FALSE; } /* add the text to the ScintillaObject */ sci_set_readonly(doc->editor->sci, FALSE); /* to allow replacing text */ sci_set_text(doc->editor->sci, filedata.data); /* NULL terminated data */ queue_colourise(doc); /* Ensure the document gets colourised. */ /* detect & set line endings */ editor_mode = utils_get_line_endings(filedata.data, filedata.len); if (undo_reload_data) { undo_reload_data->eol_mode = editor_get_eol_char_mode(doc->editor); /* Force adding an undo-reload action if the EOL mode changed. */ if (editor_mode != undo_reload_data->eol_mode) add_undo_reload_action = TRUE; } sci_set_eol_mode(doc->editor->sci, editor_mode); g_free(filedata.data); sci_set_undo_collection(doc->editor->sci, TRUE); /* If reloading and the current and new encodings or BOM states differ, * add appropriate undo actions. */ if (undo_reload_data) { if (! utils_str_equal(doc->encoding, filedata.enc)) document_undo_add(doc, UNDO_ENCODING, g_strdup(doc->encoding)); if (doc->has_bom != filedata.bom) document_undo_add(doc, UNDO_BOM, GINT_TO_POINTER(doc->has_bom)); } doc->priv->mtime = filedata.mtime; /* get the modification time from file and keep it */ g_free(doc->encoding); /* if reloading, free old encoding */ doc->encoding = filedata.enc; doc->has_bom = filedata.bom; store_saved_encoding(doc); /* store the opened encoding for undo/redo */ doc->readonly = readonly || filedata.readonly; sci_set_readonly(doc->editor->sci, doc->readonly); doc->priv->protected = 0; /* update line number margin width */ doc->priv->line_count = sci_get_line_count(doc->editor->sci); sci_set_line_numbers(doc->editor->sci, editor_prefs.show_linenumber_margin); if (! reload) { /* "the" SCI signal (connect after initial setup(i.e. adding text)) */ g_signal_connect(doc->editor->sci, "sci-notify", G_CALLBACK(editor_sci_notify_cb), doc->editor); use_ft = (ft != NULL) ? ft : filetypes_detect_from_document(doc); } else { /* reloading */ if (undo_reload_data) { /* Calculate the number of undo actions that are part of the reloading * process, and add the UNDO_RELOAD action. */ undo_reload_data->actions_count = g_trash_stack_height(&doc->priv->undo_actions) - undo_reload_data->actions_count; /* We only add an undo-reload action if the document has actually changed. * At the time of writing, this condition is moot because sci_set_text * generates an undo action even when the text hasn't really changed, so * actions_count is always greater than zero. In the future this might change. * It's arguable whether we should add an undo-reload action unconditionally, * especially since it's possible (if unlikely) that there had only * been "invisible" changes to the document, such as changes in encoding and * EOL mode, but for the time being that's how we roll. */ if (undo_reload_data->actions_count > 0 || add_undo_reload_action) document_undo_add(doc, UNDO_RELOAD, undo_reload_data); else g_free(undo_reload_data); /* We didn't save the document per-se, but its contents are now * synchronized with the file on disk, hence set a save point here. * We need to do this in this case only, because we don't clear * Scintilla's undo stack. */ sci_set_savepoint(doc->editor->sci); } else document_undo_clear(doc); use_ft = ft; } /* update taglist, typedef keywords and build menu if necessary */ document_set_filetype(doc, use_ft); /* set indentation settings after setting the filetype */ if (reload) editor_set_indent(doc->editor, doc->editor->indent_type, doc->editor->indent_width); /* resetup sci */ else document_apply_indent_settings(doc); document_set_text_changed(doc, FALSE); /* also updates tab state */ ui_document_show_hide(doc); /* update the document menu */ /* finally add current file to recent files menu, but not the files from the last session */ if (! main_status.opening_session_files) ui_add_recent_document(doc); if (reload) { g_signal_emit_by_name(geany_object, "document-reload", doc); ui_set_statusbar(TRUE, _("File %s reloaded."), display_filename); } else { g_signal_emit_by_name(geany_object, "document-open", doc); /* For translators: this is the status window message for opening a file. %d is the number * of the newly opened file, %s indicates whether the file is opened read-only * (it is replaced with the string ", read-only"). */ msgwin_status_add(_("File %s opened (%d%s)."), display_filename, gtk_notebook_get_n_pages(GTK_NOTEBOOK(main_widgets.notebook)), (readonly) ? _(", read-only") : ""); } } g_free(display_filename); g_free(utf8_filename); g_free(locale_filename); /* set the cursor position according to pos, cl_options.goto_line and cl_options.goto_column */ pos = set_cursor_position(doc->editor, pos); /* now bring the file in front */ editor_goto_pos(doc->editor, pos, FALSE); return doc; } /* Takes a new line separated list of filename URIs and opens each file. * length is the length of the string */ void document_open_file_list(const gchar *data, gsize length) { guint i; gchar **list; g_return_if_fail(data != NULL); list = g_strsplit(data, utils_get_eol_char(utils_get_line_endings(data, length)), 0); /* stop at the end or first empty item, because last item is empty but not null */ for (i = 0; list[i] != NULL && list[i][0] != '\0'; i++) { gchar *filename = utils_get_path_from_uri(list[i]); if (filename == NULL) continue; document_open_file(filename, FALSE, NULL, NULL); g_free(filename); } g_strfreev(list); } /** * Opens each file in the list @a filenames. * Internally, document_open_file() is called for every list item. * * @param filenames @elementtype{filename} A list of filenames to load, in locale encoding. * @param readonly Whether to open the document in read-only mode. * @param ft @nullable The filetype for the document or @c NULL to auto-detect the filetype. * @param forced_enc @nullable The file encoding to use or @c NULL to auto-detect the file encoding. **/ GEANY_API_SYMBOL void document_open_files(const GSList *filenames, gboolean readonly, GeanyFiletype *ft, const gchar *forced_enc) { const GSList *item; for (item = filenames; item != NULL; item = g_slist_next(item)) { document_open_file(item->data, readonly, ft, forced_enc); } } static void on_keep_edit_history_on_reload_response(GtkWidget *bar, gint response_id, GeanyDocument *doc) { if (response_id == GTK_RESPONSE_NO) { file_prefs.keep_edit_history_on_reload = FALSE; document_reload_force(doc, doc->encoding); } else if (response_id == GTK_RESPONSE_CANCEL) { /* this condition cannot be reached via info bar buttons, but by our code * to replace this bar with a higher priority one */ file_prefs.show_keep_edit_history_on_reload_msg = TRUE; } doc->priv->info_bars[MSG_TYPE_POST_RELOAD] = NULL; gtk_widget_destroy(bar); } /** * Reloads the document with the specified file encoding. * @a forced_enc or @c NULL to auto-detect the file encoding. * * @param doc The document to reload. * @param forced_enc @nullable The file encoding to use or @c NULL to auto-detect the file encoding. * * @return @c TRUE if the document was actually reloaded or @c FALSE otherwise. **/ GEANY_API_SYMBOL gboolean document_reload_force(GeanyDocument *doc, const gchar *forced_enc) { gint pos = 0; GeanyDocument *new_doc; GtkWidget *bar; g_return_val_if_fail(doc != NULL, FALSE); /* Cancel resave bar if still open from previous file deletion */ if (doc->priv->info_bars[MSG_TYPE_RESAVE] != NULL) gtk_info_bar_response(GTK_INFO_BAR(doc->priv->info_bars[MSG_TYPE_RESAVE]), GTK_RESPONSE_CANCEL); /* Use cancel because the response handler would call this recursively */ if (doc->priv->info_bars[MSG_TYPE_RELOAD] != NULL) gtk_info_bar_response(GTK_INFO_BAR(doc->priv->info_bars[MSG_TYPE_RELOAD]), GTK_RESPONSE_CANCEL); /* try to set the cursor to the position before reloading */ pos = sci_get_current_position(doc->editor->sci); new_doc = document_open_file_full(doc, NULL, pos, doc->readonly, doc->file_type, forced_enc); if (file_prefs.keep_edit_history_on_reload && file_prefs.show_keep_edit_history_on_reload_msg) { bar = document_show_message(doc, GTK_MESSAGE_INFO, on_keep_edit_history_on_reload_response, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, _("Discard history"), GTK_RESPONSE_NO, NULL, 0, _("The buffer's previous state is stored in the history and " "undoing restores it. You can disable this by discarding the history upon " "reload. This message will not be displayed again but " "your choice can be changed in the various preferences."), _("The file has been reloaded.")); doc->priv->info_bars[MSG_TYPE_POST_RELOAD] = bar; file_prefs.show_keep_edit_history_on_reload_msg = FALSE; } return (new_doc != NULL); } /* also used for reloading when forced_enc is NULL */ gboolean document_reload_prompt(GeanyDocument *doc, const gchar *forced_enc) { gchar *base_name; gboolean prompt, result = FALSE; g_return_val_if_fail(doc != NULL, FALSE); /* No need to reload "untitled" (non-file-backed) documents */ if (doc->file_name == NULL) return FALSE; if (forced_enc == NULL) forced_enc = doc->encoding; base_name = g_path_get_basename(doc->file_name); /* don't prompt if edit history is maintained, or if file hasn't been edited at all */ prompt = !file_prefs.keep_edit_history_on_reload && (doc->changed || (document_can_undo(doc) || document_can_redo(doc))); if (!prompt || dialogs_show_question_full(NULL, _("_Reload"), GTK_STOCK_CANCEL, doc->changed ? _("Any unsaved changes will be lost.") : _("Undo history will be lost."), _("Are you sure you want to reload '%s'?"), base_name)) { result = document_reload_force(doc, forced_enc); if (forced_enc != NULL) ui_update_statusbar(doc, -1); } g_free(base_name); return result; } static void document_update_timestamp(GeanyDocument *doc, const gchar *locale_filename) { #ifndef USE_GIO_FILEMON g_return_if_fail(doc != NULL); get_mtime(locale_filename, &doc->priv->mtime); /* get the modification time from file and keep it */ #endif } /* Sets line and column to the given position byte_pos in the document. * byte_pos is the position counted in bytes, not characters */ static void get_line_column_from_pos(GeanyDocument *doc, guint byte_pos, gint *line, gint *column) { gint i; gint line_start; /* for some reason we can use byte count instead of character count here */ *line = sci_get_line_from_position(doc->editor->sci, byte_pos); line_start = sci_get_position_from_line(doc->editor->sci, *line); /* get the column in the line */ *column = byte_pos - line_start; /* any non-ASCII characters are encoded with two bytes(UTF-8, always in Scintilla), so * skip one byte(i++) and decrease the column number which is based on byte count */ for (i = line_start; i < (line_start + *column); i++) { if (sci_get_char_at(doc->editor->sci, i) < 0) { (*column)--; i++; } } } static void replace_header_filename(GeanyDocument *doc) { gchar *filebase; gchar *filename; struct Sci_TextToFind ttf; g_return_if_fail(doc != NULL); g_return_if_fail(doc->file_type != NULL); filebase = g_regex_escape_string(GEANY_STRING_UNTITLED, -1); if (doc->file_type->extension) SETPTR(filebase, g_strconcat("\\b", filebase, "\\.\\w+", NULL)); else SETPTR(filebase, g_strconcat("\\b", filebase, "\\b", NULL)); filename = g_path_get_basename(doc->file_name); /* only search the first 3 lines */ ttf.chrg.cpMin = 0; ttf.chrg.cpMax = sci_get_position_from_line(doc->editor->sci, 4); ttf.lpstrText = filebase; if (search_find_text(doc->editor->sci, GEANY_FIND_MATCHCASE | GEANY_FIND_REGEXP, &ttf, NULL) != -1) { sci_set_target_start(doc->editor->sci, ttf.chrgText.cpMin); sci_set_target_end(doc->editor->sci, ttf.chrgText.cpMax); sci_replace_target(doc->editor->sci, filename, FALSE); } g_free(filebase); g_free(filename); } /** * Renames the file in @a doc to @a new_filename. Only the file on disk is actually renamed, * you still have to call @ref document_save_file_as() to change the @a doc object. * It also stops monitoring for file changes to prevent receiving too many file change events * while renaming. File monitoring is setup again in @ref document_save_file_as(). * * @param doc The current document which should be renamed. * @param new_filename The new filename in UTF-8 encoding. * * @since 0.16 **/ GEANY_API_SYMBOL void document_rename_file(GeanyDocument *doc, const gchar *new_filename) { gchar *old_locale_filename = utils_get_locale_from_utf8(doc->file_name); gchar *new_locale_filename = utils_get_locale_from_utf8(new_filename); gint result; /* stop file monitoring to avoid getting events for deleting/creating files, * it's re-setup in document_save_file_as() */ document_stop_file_monitoring(doc); result = g_rename(old_locale_filename, new_locale_filename); if (result != 0) { dialogs_show_msgbox_with_secondary(GTK_MESSAGE_ERROR, _("Error renaming file."), g_strerror(errno)); } g_free(old_locale_filename); g_free(new_locale_filename); } static void protect_document(GeanyDocument *doc) { /* do not call queue_colourise because to we want to keep the text-changed indication! */ if (!doc->priv->protected++) sci_set_readonly(doc->editor->sci, TRUE); ui_update_tab_status(doc); } static void unprotect_document(GeanyDocument *doc) { g_return_if_fail(doc->priv->protected > 0); if (!--doc->priv->protected && doc->readonly == FALSE) sci_set_readonly(doc->editor->sci, FALSE); ui_update_tab_status(doc); } /* Return TRUE if the document doesn't have a full filename set. * This makes filenames without a path show the save as dialog, e.g. for file templates. * Otherwise just use the set filename instead of asking the user - e.g. for command-line * new files. */ gboolean document_need_save_as(GeanyDocument *doc) { g_return_val_if_fail(doc != NULL, FALSE); return (doc->file_name == NULL || !g_path_is_absolute(doc->file_name)); } /** * Saves the document, detecting the filetype. * * @param doc The document for the file to save. * @param utf8_fname @nullable The new name for the document, in UTF-8, or @c NULL. * @return @c TRUE if the file was saved or @c FALSE if the file could not be saved. * * @see document_save_file(). * * @since 0.16 **/ GEANY_API_SYMBOL gboolean document_save_file_as(GeanyDocument *doc, const gchar *utf8_fname) { gboolean ret; gboolean new_file; g_return_val_if_fail(doc != NULL, FALSE); new_file = document_need_save_as(doc) || (utf8_fname != NULL && strcmp(doc->file_name, utf8_fname) != 0); if (utf8_fname != NULL) SETPTR(doc->file_name, g_strdup(utf8_fname)); /* reset real path, it's retrieved again in document_save() */ SETPTR(doc->real_path, NULL); /* detect filetype */ if (doc->file_type->id == GEANY_FILETYPES_NONE) { GeanyFiletype *ft = filetypes_detect_from_document(doc); document_set_filetype(doc, ft); if (document_get_current() == doc) { ignore_callback = TRUE; filetypes_select_radio_item(doc->file_type); ignore_callback = FALSE; } } if (new_file) { // assume user wants to throw away read-only setting sci_set_readonly(doc->editor->sci, FALSE); doc->readonly = FALSE; if (doc->priv->protected > 0) unprotect_document(doc); } replace_header_filename(doc); ret = document_save_file(doc, TRUE); /* file monitoring support, add file monitoring after the file has been saved * to ignore any earlier events */ monitor_file_setup(doc); doc->priv->file_disk_status = FILE_IGNORE; return ret; } static gsize save_convert_to_encoding(GeanyDocument *doc, gchar **data, gsize *len) { GError *conv_error = NULL; gchar* conv_file_contents = NULL; gsize bytes_read; gsize conv_len; g_return_val_if_fail(data != NULL && *data != NULL, FALSE); g_return_val_if_fail(len != NULL, FALSE); /* try to convert it from UTF-8 to original encoding */ conv_file_contents = g_convert(*data, *len - 1, doc->encoding, "UTF-8", &bytes_read, &conv_len, &conv_error); if (conv_error != NULL) { gchar *text = g_strdup_printf( _("An error occurred while converting the file from UTF-8 in \"%s\". The file remains unsaved."), doc->encoding); gchar *error_text; if (conv_error->code == G_CONVERT_ERROR_ILLEGAL_SEQUENCE) { gint line, column; gint context_len; gunichar unic; /* don't read over the doc length */ gint max_len = MIN((gint)bytes_read + 6, (gint)*len - 1); gchar context[7]; /* read 6 bytes from Sci + '\0' */ sci_get_text_range(doc->editor->sci, bytes_read, max_len, context); /* take only one valid Unicode character from the context and discard the leftover */ unic = g_utf8_get_char_validated(context, -1); context_len = g_unichar_to_utf8(unic, context); context[context_len] = '\0'; get_line_column_from_pos(doc, bytes_read, &line, &column); error_text = g_strdup_printf( _("Error message: %s\nThe error occurred at \"%s\" (line: %d, column: %d)."), conv_error->message, context, line + 1, column); } else error_text = g_strdup_printf(_("Error message: %s."), conv_error->message); geany_debug("encoding error: %s", conv_error->message); dialogs_show_msgbox_with_secondary(GTK_MESSAGE_ERROR, text, error_text); g_error_free(conv_error); g_free(text); g_free(error_text); return FALSE; } else { g_free(*data); *data = conv_file_contents; *len = conv_len; } return TRUE; } static gchar *write_data_to_disk(const gchar *locale_filename, const gchar *data, gsize len) { GError *error = NULL; if (file_prefs.use_safe_file_saving) { /* Use old GLib API for safe saving (GVFS-safe, but alters ownership and permissons). * This is the only option that handles disk space exhaustion. */ if (g_file_set_contents(locale_filename, data, len, &error)) geany_debug("Wrote %s with g_file_set_contents().", locale_filename); } else if (USE_GIO_FILE_OPERATIONS) { GFile *fp; /* Use GIO API to save file (GVFS-safe) * It is best in most GVFS setups but don't seem to work correctly on some more complex * setups (saving from some VM to their host, over some SMB shares, etc.) */ fp = g_file_new_for_path(locale_filename); g_file_replace_contents(fp, data, len, NULL, file_prefs.gio_unsafe_save_backup, G_FILE_CREATE_NONE, NULL, NULL, &error); g_object_unref(fp); } else { FILE *fp; int save_errno; gchar *display_name = g_filename_display_name(locale_filename); /* Use POSIX API for unsafe saving (GVFS-unsafe) */ /* The error handling is taken from glib-2.26.0 gfileutils.c */ errno = 0; fp = g_fopen(locale_filename, "wb"); if (fp == NULL) { save_errno = errno; g_set_error(&error, G_FILE_ERROR, g_file_error_from_errno(save_errno), _("Failed to open file '%s' for writing: fopen() failed: %s"), display_name, g_strerror(save_errno)); } else { gsize bytes_written; errno = 0; bytes_written = fwrite(data, sizeof(gchar), len, fp); if (len != bytes_written) { save_errno = errno; g_set_error(&error, G_FILE_ERROR, g_file_error_from_errno(save_errno), _("Failed to write file '%s': fwrite() failed: %s"), display_name, g_strerror(save_errno)); } errno = 0; /* preserve the fwrite() error if any */ if (fclose(fp) != 0 && error == NULL) { save_errno = errno; g_set_error(&error, G_FILE_ERROR, g_file_error_from_errno(save_errno), _("Failed to close file '%s': fclose() failed: %s"), display_name, g_strerror(save_errno)); } } g_free(display_name); } if (error != NULL) { gchar *msg = g_strdup(error->message); g_error_free(error); /* geany will warn about file truncation for unsafe saving below */ return msg; } return NULL; } static gchar *save_doc(GeanyDocument *doc, const gchar *locale_filename, const gchar *data, gsize len) { gchar *err; g_return_val_if_fail(doc != NULL, g_strdup(g_strerror(EINVAL))); g_return_val_if_fail(data != NULL, g_strdup(g_strerror(EINVAL))); err = write_data_to_disk(locale_filename, data, len); if (err) return err; /* now the file is on disk, set real_path */ if (doc->real_path == NULL) { doc->real_path = utils_get_real_path(locale_filename); doc->priv->is_remote = utils_is_remote_path(locale_filename); monitor_file_setup(doc); ui_add_recent_document(doc); } return NULL; } static gboolean save_file_handle_infobars(GeanyDocument *doc, gboolean force) { GtkWidget *bar = NULL; document_show_tab(doc); if (doc->priv->info_bars[MSG_TYPE_RELOAD]) { if (!dialogs_show_question_full(NULL, _("_Overwrite"), GTK_STOCK_CANCEL, _("Overwrite?"), _("The file '%s' on the disk is more recent than the current buffer."), doc->file_name)) return FALSE; bar = doc->priv->info_bars[MSG_TYPE_RELOAD]; } else if (doc->priv->info_bars[MSG_TYPE_RESAVE]) { if (!dialogs_show_question_full(NULL, GTK_STOCK_SAVE, GTK_STOCK_CANCEL, _("Try to resave the file?"), _("File \"%s\" was not found on disk!"), doc->file_name)) return FALSE; bar = doc->priv->info_bars[MSG_TYPE_RESAVE]; } else { g_assert_not_reached(); return FALSE; } gtk_info_bar_response(GTK_INFO_BAR(bar), RESPONSE_DOCUMENT_SAVE); return TRUE; } /** * Saves the document. * Also shows the Save As dialog if necessary. * If the file is not modified, this function may do nothing unless @a force is set to @c TRUE. * * Saving may include replacing tabs with spaces, * stripping trailing spaces and adding a final new line at the end of the file, depending * on user preferences. Then the @c "document-before-save" signal is emitted, * allowing plugins to modify the document before it is saved, and data is * actually written to disk. * * On successful saving: * - GeanyDocument::real_path is set. * - The filetype is set again or auto-detected if it wasn't set yet. * - The @c "document-save" signal is emitted for plugins. * * @warning You should ensure @c doc->file_name has an absolute path unless you want the * Save As dialog to be shown. A @c NULL value also shows the dialog. This behaviour was * added in Geany 1.22. * * @param doc The document to save. * @param force Whether to save the file even if it is not modified. * * @return @c TRUE if the file was saved or @c FALSE if the file could not or should not be saved. **/ GEANY_API_SYMBOL gboolean document_save_file(GeanyDocument *doc, gboolean force) { gchar *errmsg; gchar *data; gsize len; gchar *locale_filename; const GeanyFilePrefs *fp; g_return_val_if_fail(doc != NULL, FALSE); if (document_need_save_as(doc)) { /* ensure doc is the current tab before showing the dialog */ document_show_tab(doc); return dialogs_show_save_as(); } if (!force && !doc->changed) return FALSE; if (doc->readonly) { ui_set_statusbar(TRUE, _("Cannot save read-only document '%s'!"), DOC_FILENAME(doc)); return FALSE; } document_check_disk_status(doc, TRUE); if (doc->priv->protected) return save_file_handle_infobars(doc, force); fp = project_get_file_prefs(); /* replaces tabs with spaces but only if the current file is not a Makefile */ if (fp->replace_tabs && doc->file_type->id != GEANY_FILETYPES_MAKE) editor_replace_tabs(doc->editor, TRUE); /* strip trailing spaces */ if (fp->strip_trailing_spaces) editor_strip_trailing_spaces(doc->editor, TRUE); /* ensure the file has a newline at the end */ if (fp->final_new_line) editor_ensure_final_newline(doc->editor); /* ensure newlines are consistent */ if (fp->ensure_convert_new_lines) sci_convert_eols(doc->editor->sci, sci_get_eol_mode(doc->editor->sci)); /* notify plugins which may wish to modify the document before it's saved */ g_signal_emit_by_name(geany_object, "document-before-save", doc); len = sci_get_length(doc->editor->sci) + 1; if (doc->has_bom && encodings_is_unicode_charset(doc->encoding)) { /* always write a UTF-8 BOM because in this moment the text itself is still in UTF-8 * encoding, it will be converted to doc->encoding below and this conversion * also changes the BOM */ data = (gchar*) g_malloc(len + 3); /* 3 chars for BOM */ data[0] = (gchar) 0xef; data[1] = (gchar) 0xbb; data[2] = (gchar) 0xbf; sci_get_text(doc->editor->sci, len, data + 3); len += 3; } else { data = (gchar*) g_malloc(len); sci_get_text(doc->editor->sci, len, data); } /* save in original encoding, skip when it is already UTF-8 or has the encoding "None" */ if (doc->encoding != NULL && ! utils_str_equal(doc->encoding, "UTF-8") && ! utils_str_equal(doc->encoding, encodings[GEANY_ENCODING_NONE].charset)) { if (! save_convert_to_encoding(doc, &data, &len)) { g_free(data); return FALSE; } } else { len = strlen(data); } locale_filename = utils_get_locale_from_utf8(doc->file_name); /* ignore file changed notification when the file is written */ doc->priv->file_disk_status = FILE_IGNORE; /* actually write the content of data to the file on disk */ errmsg = save_doc(doc, locale_filename, data, len); g_free(data); if (errmsg != NULL) { ui_set_statusbar(TRUE, _("Error saving file (%s)."), errmsg); if (!file_prefs.use_safe_file_saving) { SETPTR(errmsg, g_strdup_printf(_("%s\n\nThe file on disk may now be truncated!"), errmsg)); } dialogs_show_msgbox_with_secondary(GTK_MESSAGE_ERROR, _("Error saving file."), errmsg); doc->priv->file_disk_status = FILE_OK; utils_beep(); g_free(locale_filename); g_free(errmsg); return FALSE; } /* store the opened encoding for undo/redo */ store_saved_encoding(doc); /* ignore the following things if we are quitting */ if (! main_status.quitting) { sci_set_savepoint(doc->editor->sci); if (file_prefs.disk_check_timeout > 0) document_update_timestamp(doc, locale_filename); /* update filetype-related things */ document_set_filetype(doc, doc->file_type); document_update_tab_label(doc); msgwin_status_add(_("File %s saved."), doc->file_name); ui_update_statusbar(doc, -1); #ifdef HAVE_VTE vte_cwd((doc->real_path != NULL) ? doc->real_path : doc->file_name, FALSE); #endif } g_free(locale_filename); g_signal_emit_by_name(geany_object, "document-save", doc); return TRUE; } /* special search function, used from the find entry in the toolbar * return TRUE if text was found otherwise FALSE * return also TRUE if text is empty */ gboolean document_search_bar_find(GeanyDocument *doc, const gchar *text, gboolean inc, gboolean backwards) { gint start_pos, search_pos; struct Sci_TextToFind ttf; g_return_val_if_fail(text != NULL, FALSE); g_return_val_if_fail(doc != NULL, FALSE); if (! *text) return TRUE; start_pos = (inc || backwards) ? sci_get_selection_start(doc->editor->sci) : sci_get_selection_end(doc->editor->sci); /* equal if no selection */ /* search cursor to end or start */ ttf.chrg.cpMin = start_pos; ttf.chrg.cpMax = backwards ? 0 : sci_get_length(doc->editor->sci); ttf.lpstrText = (gchar *)text; search_pos = sci_find_text(doc->editor->sci, 0, &ttf); /* if no match, search start (or end) to cursor */ if (search_pos == -1) { if (backwards) { ttf.chrg.cpMin = sci_get_length(doc->editor->sci); ttf.chrg.cpMax = start_pos; } else { ttf.chrg.cpMin = 0; ttf.chrg.cpMax = start_pos + strlen(text); } search_pos = sci_find_text(doc->editor->sci, 0, &ttf); } if (search_pos != -1) { gint line = sci_get_line_from_position(doc->editor->sci, ttf.chrgText.cpMin); /* unfold maybe folded results */ sci_ensure_line_is_visible(doc->editor->sci, line); sci_set_selection_start(doc->editor->sci, ttf.chrgText.cpMin); sci_set_selection_end(doc->editor->sci, ttf.chrgText.cpMax); if (! editor_line_in_view(doc->editor, line)) { /* we need to force scrolling in case the cursor is outside of the current visible area * GeanyDocument::scroll_percent doesn't work because sci isn't always updated * while searching */ editor_scroll_to_line(doc->editor, -1, 0.3F); } else sci_scroll_caret(doc->editor->sci); /* may need horizontal scrolling */ return TRUE; } else { if (! inc) { ui_set_statusbar(FALSE, _("\"%s\" was not found."), text); } utils_beep(); sci_goto_pos(doc->editor->sci, start_pos, FALSE); /* clear selection */ return FALSE; } } /* General search function, used from the find dialog. * Returns -1 on failure or the start position of the matching text. * Will skip past any selection, ignoring it. * * @param text Text to find. * @param original_text Text as it was entered by user, or @c NULL to use @c text */ gint document_find_text(GeanyDocument *doc, const gchar *text, const gchar *original_text, GeanyFindFlags flags, gboolean search_backwards, GeanyMatchInfo **match_, gboolean scroll, GtkWidget *parent) { gint selection_end, selection_start, search_pos; g_return_val_if_fail(doc != NULL && text != NULL, -1); if (! *text) return -1; /* Sci doesn't support searching backwards with a regex */ if (flags & GEANY_FIND_REGEXP) search_backwards = FALSE; if (!original_text) original_text = text; selection_start = sci_get_selection_start(doc->editor->sci); selection_end = sci_get_selection_end(doc->editor->sci); if ((selection_end - selection_start) > 0) { /* there's a selection so go to the end */ if (search_backwards) sci_goto_pos(doc->editor->sci, selection_start, TRUE); else sci_goto_pos(doc->editor->sci, selection_end, TRUE); } sci_set_search_anchor(doc->editor->sci); if (search_backwards) search_pos = search_find_prev(doc->editor->sci, text, flags, match_); else search_pos = search_find_next(doc->editor->sci, text, flags, match_); if (search_pos != -1) { /* unfold maybe folded results */ sci_ensure_line_is_visible(doc->editor->sci, sci_get_line_from_position(doc->editor->sci, search_pos)); if (scroll) doc->editor->scroll_percent = 0.3F; } else { gint sci_len = sci_get_length(doc->editor->sci); /* if we just searched the whole text, give up searching. */ if ((selection_end == 0 && ! search_backwards) || (selection_end == sci_len && search_backwards)) { ui_set_statusbar(FALSE, _("\"%s\" was not found."), original_text); utils_beep(); return -1; } /* we searched only part of the document, so ask whether to wraparound. */ if (search_prefs.always_wrap || dialogs_show_question_full(parent, GTK_STOCK_FIND, GTK_STOCK_CANCEL, _("Wrap search and find again?"), _("\"%s\" was not found."), original_text)) { gint ret; sci_set_current_position(doc->editor->sci, (search_backwards) ? sci_len : 0, FALSE); ret = document_find_text(doc, text, original_text, flags, search_backwards, match_, scroll, parent); if (ret == -1) { /* return to original cursor position if not found */ sci_set_current_position(doc->editor->sci, selection_start, FALSE); } return ret; } } return search_pos; } /* Replaces the selection if it matches, otherwise just finds the next match. * Returns: start of replaced text, or -1 if no replacement was made * * @param find_text Text to find. * @param original_find_text Text to find as it was entered by user, or @c NULL to use @c find_text */ gint document_replace_text(GeanyDocument *doc, const gchar *find_text, const gchar *original_find_text, const gchar *replace_text, GeanyFindFlags flags, gboolean search_backwards) { gint selection_end, selection_start, search_pos; GeanyMatchInfo *match = NULL; g_return_val_if_fail(doc != NULL && find_text != NULL && replace_text != NULL, -1); if (! *find_text) return -1; /* Sci doesn't support searching backwards with a regex */ if (flags & GEANY_FIND_REGEXP) search_backwards = FALSE; if (!original_find_text) original_find_text = find_text; selection_start = sci_get_selection_start(doc->editor->sci); selection_end = sci_get_selection_end(doc->editor->sci); if (selection_end == selection_start) { /* no selection so just find the next match */ document_find_text(doc, find_text, original_find_text, flags, search_backwards, NULL, TRUE, NULL); return -1; } /* there's a selection so go to the start before finding to search through it * this ensures there is a match */ if (search_backwards) sci_goto_pos(doc->editor->sci, selection_end, TRUE); else sci_goto_pos(doc->editor->sci, selection_start, TRUE); search_pos = document_find_text(doc, find_text, original_find_text, flags, search_backwards, &match, TRUE, NULL); /* return if the original selected text did not match (at the start of the selection) */ if (search_pos != selection_start) { if (search_pos != -1) geany_match_info_free(match); return -1; } if (search_pos != -1) { gint replace_len = search_replace_match(doc->editor->sci, match, replace_text); /* select the replacement - find text will skip past the selected text */ sci_set_selection_start(doc->editor->sci, search_pos); sci_set_selection_end(doc->editor->sci, search_pos + replace_len); geany_match_info_free(match); } else { /* no match in the selection */ utils_beep(); } return search_pos; } static void show_replace_summary(GeanyDocument *doc, gint count, const gchar *original_find_text, const gchar *original_replace_text) { gchar *filename; if (count == 0) { ui_set_statusbar(FALSE, _("No matches found for \"%s\"."), original_find_text); return; } filename = g_path_get_basename(DOC_FILENAME(doc)); ui_set_statusbar(TRUE, ngettext( "%s: replaced %d occurrence of \"%s\" with \"%s\".", "%s: replaced %d occurrences of \"%s\" with \"%s\".", count), filename, count, original_find_text, original_replace_text); g_free(filename); } /* Replace all text matches in a certain range within document. * If not NULL, *new_range_end is set to the new range endpoint after replacing, * or -1 if no text was found. * scroll_to_match is whether to scroll the last replacement in view (which also * clears the selection). * Returns: the number of replacements made. */ static guint document_replace_range(GeanyDocument *doc, const gchar *find_text, const gchar *replace_text, GeanyFindFlags flags, gint start, gint end, gboolean scroll_to_match, gint *new_range_end) { gint count = 0; struct Sci_TextToFind ttf; ScintillaObject *sci; if (new_range_end != NULL) *new_range_end = -1; g_return_val_if_fail(doc != NULL && find_text != NULL && replace_text != NULL, 0); if (! *find_text || doc->readonly) return 0; sci = doc->editor->sci; ttf.chrg.cpMin = start; ttf.chrg.cpMax = end; ttf.lpstrText = (gchar*)find_text; sci_start_undo_action(sci); count = search_replace_range(sci, &ttf, flags, replace_text); sci_end_undo_action(sci); if (count > 0) { /* scroll last match in view, will destroy the existing selection */ if (scroll_to_match) sci_goto_pos(sci, ttf.chrg.cpMin, TRUE); if (new_range_end != NULL) *new_range_end = ttf.chrg.cpMax; } return count; } void document_replace_sel(GeanyDocument *doc, const gchar *find_text, const gchar *replace_text, const gchar *original_find_text, const gchar *original_replace_text, GeanyFindFlags flags) { gint selection_end, selection_start, selection_mode, selected_lines, last_line = 0; gint max_column = 0, count = 0; gboolean replaced = FALSE; g_return_if_fail(doc != NULL && find_text != NULL && replace_text != NULL); if (! *find_text) return; selection_start = sci_get_selection_start(doc->editor->sci); selection_end = sci_get_selection_end(doc->editor->sci); /* do we have a selection? */ if ((selection_end - selection_start) == 0) { utils_beep(); return; } selection_mode = sci_get_selection_mode(doc->editor->sci); selected_lines = sci_get_lines_selected(doc->editor->sci); /* handle rectangle, multi line selections (it doesn't matter on a single line) */ if (selection_mode == SC_SEL_RECTANGLE && selected_lines > 1) { gint first_line, line; sci_start_undo_action(doc->editor->sci); first_line = sci_get_line_from_position(doc->editor->sci, selection_start); /* Find the last line with chars selected (not EOL char) */ last_line = sci_get_line_from_position(doc->editor->sci, selection_end - editor_get_eol_char_len(doc->editor)); last_line = MAX(first_line, last_line); for (line = first_line; line < (first_line + selected_lines); line++) { gint line_start = sci_get_pos_at_line_sel_start(doc->editor->sci, line); gint line_end = sci_get_pos_at_line_sel_end(doc->editor->sci, line); /* skip line if there is no selection */ if (line_start != INVALID_POSITION) { /* don't let document_replace_range() scroll to match to keep our selection */ gint new_sel_end; count += document_replace_range(doc, find_text, replace_text, flags, line_start, line_end, FALSE, &new_sel_end); if (new_sel_end != -1) { replaced = TRUE; /* this gets the greatest column within the selection after replacing */ max_column = MAX(max_column, new_sel_end - sci_get_position_from_line(doc->editor->sci, line)); } } } sci_end_undo_action(doc->editor->sci); } else /* handle normal line selection */ { count += document_replace_range(doc, find_text, replace_text, flags, selection_start, selection_end, TRUE, &selection_end); if (selection_end != -1) replaced = TRUE; } if (replaced) { /* update the selection for the new endpoint */ if (selection_mode == SC_SEL_RECTANGLE && selected_lines > 1) { /* now we can scroll to the selection and destroy it because we rebuild it later */ /*sci_goto_pos(doc->editor->sci, selection_start, FALSE);*/ /* Note: the selection will be wrapped to last_line + 1 if max_column is greater than * the highest column on the last line. The wrapped selection is completely different * from the original one, so skip the selection at all */ /* TODO is there a better way to handle the wrapped selection? */ if ((sci_get_line_length(doc->editor->sci, last_line) - 1) >= max_column) { /* for keeping and adjusting the selection in multi line rectangle selection we * need the last line of the original selection and the greatest column number after * replacing and set the selection end to the last line at the greatest column */ sci_set_selection_start(doc->editor->sci, selection_start); sci_set_selection_end(doc->editor->sci, sci_get_position_from_line(doc->editor->sci, last_line) + max_column); sci_set_selection_mode(doc->editor->sci, selection_mode); } } else { sci_set_selection_start(doc->editor->sci, selection_start); sci_set_selection_end(doc->editor->sci, selection_end); } } else /* no replacements */ utils_beep(); show_replace_summary(doc, count, original_find_text, original_replace_text); } /* returns number of replacements made. */ gint document_replace_all(GeanyDocument *doc, const gchar *find_text, const gchar *replace_text, const gchar *original_find_text, const gchar *original_replace_text, GeanyFindFlags flags) { gint len, count; g_return_val_if_fail(doc != NULL && find_text != NULL && replace_text != NULL, FALSE); if (! *find_text) return FALSE; len = sci_get_length(doc->editor->sci); count = document_replace_range( doc, find_text, replace_text, flags, 0, len, TRUE, NULL); show_replace_summary(doc, count, original_find_text, original_replace_text); return count; } /* * Parses or re-parses the document's buffer and updates the type * keywords and symbol list. * * @param doc The document. */ void document_update_tags(GeanyDocument *doc) { guchar *buffer_ptr; gsize len; g_return_if_fail(DOC_VALID(doc)); g_return_if_fail(app->tm_workspace != NULL); /* early out if it's a new file or doesn't support tags */ if (! doc->file_name || ! doc->file_type || !filetype_has_tags(doc->file_type)) { /* We must call sidebar_update_tag_list() before returning, * to ensure that the symbol list is always updated properly (e.g. * when creating a new document with a partial filename set. */ sidebar_update_tag_list(doc, FALSE); return; } /* create a new TM file if there isn't one yet */ if (! doc->tm_file) { gchar *locale_filename = utils_get_locale_from_utf8(doc->file_name); const gchar *name; /* lookup the name rather than using filetype name to support custom filetypes */ name = tm_source_file_get_lang_name(doc->file_type->lang); doc->tm_file = tm_source_file_new(locale_filename, name); g_free(locale_filename); if (doc->tm_file) tm_workspace_add_source_file_noupdate(doc->tm_file); } /* early out if there's no tm source file and we couldn't create one */ if (doc->tm_file == NULL) { /* We must call sidebar_update_tag_list() before returning, * to ensure that the symbol list is always updated properly (e.g. * when creating a new document with a partial filename set. */ sidebar_update_tag_list(doc, FALSE); return; } /* Parse Scintilla's buffer directly using TagManager * Note: this buffer *MUST NOT* be modified */ len = sci_get_length(doc->editor->sci); buffer_ptr = (guchar *) SSM(doc->editor->sci, SCI_GETCHARACTERPOINTER, 0, 0); tm_workspace_update_source_file_buffer(doc->tm_file, buffer_ptr, len); sidebar_update_tag_list(doc, TRUE); document_highlight_tags(doc); } /* Re-highlights type keywords without re-parsing the whole document. */ void document_highlight_tags(GeanyDocument *doc) { GString *keywords_str; gint keyword_idx; /* some filetypes support type keywords (such as struct names), but not * necessarily all filetypes for a particular scintilla lexer. this * tells us whether the filetype supports keywords, and if so * which index to use for the scintilla keywords set. */ switch (doc->file_type->id) { case GEANY_FILETYPES_C: case GEANY_FILETYPES_CPP: case GEANY_FILETYPES_CS: case GEANY_FILETYPES_D: case GEANY_FILETYPES_JAVA: case GEANY_FILETYPES_OBJECTIVEC: case GEANY_FILETYPES_VALA: case GEANY_FILETYPES_RUST: case GEANY_FILETYPES_GO: { /* index of the keyword set in the Scintilla lexer, for * example in LexCPP.cxx, see "cppWordLists" global array. * TODO: this magic number should be a member of the filetype */ keyword_idx = 3; break; } default: return; /* early out if type keywords are not supported */ } if (!app->tm_workspace->tags_array) return; /* get any type keywords and tell scintilla about them * this will cause the type keywords to be colourized in scintilla */ keywords_str = symbols_find_typenames_as_string(doc->file_type->lang, FALSE); if (keywords_str) { gchar *keywords = g_string_free(keywords_str, FALSE); guint hash = g_str_hash(keywords); if (hash != doc->priv->keyword_hash) { sci_set_keywords(doc->editor->sci, keyword_idx, keywords); queue_colourise(doc); /* force re-highlighting the entire document */ doc->priv->keyword_hash = hash; } g_free(keywords); } } static gboolean on_document_update_tag_list_idle(gpointer data) { GeanyDocument *doc = data; if (! DOC_VALID(doc)) return FALSE; if (! main_status.quitting) document_update_tags(doc); doc->priv->tag_list_update_source = 0; /* don't update the tags until another modification of the buffer */ return FALSE; } void document_update_tag_list_in_idle(GeanyDocument *doc) { if (editor_prefs.autocompletion_update_freq <= 0 || ! filetype_has_tags(doc->file_type)) return; /* prevent "stacking up" callback handlers, we only need one to run soon */ if (doc->priv->tag_list_update_source != 0) g_source_remove(doc->priv->tag_list_update_source); doc->priv->tag_list_update_source = g_timeout_add_full(G_PRIORITY_LOW, editor_prefs.autocompletion_update_freq, on_document_update_tag_list_idle, doc, NULL); } static void document_load_config(GeanyDocument *doc, GeanyFiletype *type, gboolean filetype_changed) { g_return_if_fail(doc); if (type == NULL) type = filetypes[GEANY_FILETYPES_NONE]; if (filetype_changed) { doc->file_type = type; /* delete tm file object to force creation of a new one */ if (doc->tm_file != NULL) { tm_workspace_remove_source_file(doc->tm_file); tm_source_file_free(doc->tm_file); doc->tm_file = NULL; } /* load tags files before highlighting (some lexers highlight global typenames) */ if (type->id != GEANY_FILETYPES_NONE) symbols_global_tags_loaded(type->id); highlighting_set_styles(doc->editor->sci, type); editor_set_indentation_guides(doc->editor); build_menu_update(doc); queue_colourise(doc); /* forces re-setting SCI_SETKEYWORDS which seems to be needed with * Scintilla 5 to colorize them properly */ doc->priv->keyword_hash = 0; if (type->priv->symbol_list_sort_mode == SYMBOLS_SORT_USE_PREVIOUS) doc->priv->symbol_list_sort_mode = interface_prefs.symbols_sort_mode; else doc->priv->symbol_list_sort_mode = type->priv->symbol_list_sort_mode; } document_update_tags(doc); } /** Sets the filetype of the document (which controls syntax highlighting and tags) * @param doc The document to use. * @param type The filetype. */ GEANY_API_SYMBOL void document_set_filetype(GeanyDocument *doc, GeanyFiletype *type) { gboolean ft_changed; GeanyFiletype *old_ft; g_return_if_fail(doc); if (type == NULL) type = filetypes[GEANY_FILETYPES_NONE]; old_ft = doc->file_type; geany_debug("%s : %s (%s)", (doc->file_name != NULL) ? doc->file_name : "unknown", type->name, (doc->encoding != NULL) ? doc->encoding : "unknown"); ft_changed = (doc->file_type != type); /* filetype has changed */ document_load_config(doc, type, ft_changed); if (ft_changed) { const GeanyIndentPrefs *iprefs = editor_get_indent_prefs(NULL); /* assume that if previous filetype was none and the settings are the default ones, this * is the first time the filetype is carefully set, so we should apply indent settings */ if ((! old_ft || old_ft->id == GEANY_FILETYPES_NONE) && doc->editor->indent_type == iprefs->type && doc->editor->indent_width == iprefs->width) { document_apply_indent_settings(doc); ui_document_show_hide(doc); } sidebar_openfiles_update(doc); /* to update the icon */ g_signal_emit_by_name(geany_object, "document-filetype-set", doc, old_ft); } } void document_reload_config(GeanyDocument *doc) { document_load_config(doc, doc->file_type, TRUE); } /** * Sets the encoding of a document. * This function only set the encoding of the %document, it does not any conversions. The new * encoding is used when e.g. saving the file. * * @param doc The document to use. * @param new_encoding The encoding to be set for the document. **/ GEANY_API_SYMBOL void document_set_encoding(GeanyDocument *doc, const gchar *new_encoding) { if (doc == NULL || new_encoding == NULL || utils_str_equal(new_encoding, doc->encoding)) return; g_free(doc->encoding); doc->encoding = g_strdup(new_encoding); ui_update_statusbar(doc, -1); gtk_widget_set_sensitive(ui_lookup_widget(main_widgets.window, "menu_write_unicode_bom1"), encodings_is_unicode_charset(doc->encoding)); } /* own Undo / Redo implementation to be able to undo / redo changes * to the encoding or the Unicode BOM (which are Scintilla independet). * All Scintilla events are stored in the undo / redo buffer and are passed through. */ /* Clears an Undo or Redo buffer. */ void document_undo_clear_stack(GTrashStack **stack) { while (g_trash_stack_height(stack) > 0) { undo_action *a = g_trash_stack_pop(stack); if (G_LIKELY(a != NULL)) { switch (a->type) { case UNDO_ENCODING: case UNDO_RELOAD: g_free(a->data); break; default: break; } g_free(a); } } *stack = NULL; } /* Clears the Undo and Redo buffer (to be called when reloading or closing the document) */ void document_undo_clear(GeanyDocument *doc) { document_undo_clear_stack(&doc->priv->undo_actions); document_undo_clear_stack(&doc->priv->redo_actions); if (! main_status.quitting && doc->editor != NULL) document_set_text_changed(doc, FALSE); } /* Adds an undo action without clearing the redo stack. This function should * not be called directly, generally (use document_undo_add() instead), but is * used by document_redo() in order not to erase the redo stack while moving * an action from the redo stack to the undo stack. */ void document_undo_add_internal(GeanyDocument *doc, guint type, gpointer data) { undo_action *action; g_return_if_fail(doc != NULL); action = g_new0(undo_action, 1); action->type = type; action->data = data; g_trash_stack_push(&doc->priv->undo_actions, action); /* avoid unnecessary redraws */ if (type != UNDO_SCINTILLA || !doc->changed) document_set_text_changed(doc, TRUE); ui_update_popup_reundo_items(doc); } /* note: this is called on SCN_MODIFIED notifications */ void document_undo_add(GeanyDocument *doc, guint type, gpointer data) { /* Clear the redo actions stack before adding the undo action. */ document_undo_clear_stack(&doc->priv->redo_actions); document_undo_add_internal(doc, type, data); } gboolean document_can_undo(GeanyDocument *doc) { g_return_val_if_fail(doc != NULL, FALSE); if (g_trash_stack_height(&doc->priv->undo_actions) > 0 || sci_can_undo(doc->editor->sci)) return TRUE; else return FALSE; } static void update_changed_state(GeanyDocument *doc) { doc->changed = (sci_is_modified(doc->editor->sci) || doc->has_bom != doc->priv->saved_encoding.has_bom || ! utils_str_equal(doc->encoding, doc->priv->saved_encoding.encoding)); document_set_text_changed(doc, doc->changed); } void document_undo(GeanyDocument *doc) { undo_action *action; g_return_if_fail(doc != NULL); action = g_trash_stack_pop(&doc->priv->undo_actions); if (G_UNLIKELY(action == NULL)) { /* fallback, should not be necessary */ geany_debug("%s: fallback used", G_STRFUNC); sci_undo(doc->editor->sci); } else { switch (action->type) { case UNDO_SCINTILLA: { document_redo_add(doc, UNDO_SCINTILLA, NULL); sci_undo(doc->editor->sci); break; } case UNDO_BOM: { document_redo_add(doc, UNDO_BOM, GINT_TO_POINTER(doc->has_bom)); doc->has_bom = GPOINTER_TO_INT(action->data); ui_update_statusbar(doc, -1); ui_document_show_hide(doc); break; } case UNDO_ENCODING: { /* use the "old" encoding */ document_redo_add(doc, UNDO_ENCODING, g_strdup(doc->encoding)); document_set_encoding(doc, (const gchar*)action->data); g_free(action->data); ui_update_statusbar(doc, -1); ui_document_show_hide(doc); break; } case UNDO_EOL: { undo_action *next_action; document_redo_add(doc, UNDO_EOL, GINT_TO_POINTER(sci_get_eol_mode(doc->editor->sci))); sci_set_eol_mode(doc->editor->sci, GPOINTER_TO_INT(action->data)); ui_update_statusbar(doc, -1); ui_document_show_hide(doc); /* When undoing, UNDO_EOL is always followed by UNDO_SCINTILLA * which undos the line endings in the editor and should be * performed together with UNDO_EOL. */ next_action = g_trash_stack_peek(&doc->priv->undo_actions); if (next_action && next_action->type == UNDO_SCINTILLA) document_undo(doc); break; } case UNDO_RELOAD: { UndoReloadData *data = (UndoReloadData*)action->data; gint eol_mode = data->eol_mode; guint i; /* We reuse 'data' for the redo action, so read the current EOL mode * into it before proceeding. */ data->eol_mode = editor_get_eol_char_mode(doc->editor); /* Undo the rest of the actions which are part of the reloading process. */ for (i = 0; i < data->actions_count; i++) document_undo(doc); /* Restore the previous EOL mode. */ sci_set_eol_mode(doc->editor->sci, eol_mode); /* This might affect the status bar and document menu, so update them. */ ui_update_statusbar(doc, -1); ui_document_show_hide(doc); document_redo_add(doc, UNDO_RELOAD, data); break; } default: break; } } g_free(action); /* free the action which was taken from the stack */ update_changed_state(doc); ui_update_popup_reundo_items(doc); } gboolean document_can_redo(GeanyDocument *doc) { g_return_val_if_fail(doc != NULL, FALSE); if (g_trash_stack_height(&doc->priv->redo_actions) > 0 || sci_can_redo(doc->editor->sci)) return TRUE; else return FALSE; } void document_redo(GeanyDocument *doc) { undo_action *action; g_return_if_fail(doc != NULL); action = g_trash_stack_pop(&doc->priv->redo_actions); if (G_UNLIKELY(action == NULL)) { /* fallback, should not be necessary */ geany_debug("%s: fallback used", G_STRFUNC); sci_redo(doc->editor->sci); } else { switch (action->type) { case UNDO_SCINTILLA: { undo_action *next_action; document_undo_add_internal(doc, UNDO_SCINTILLA, NULL); sci_redo(doc->editor->sci); /* When redoing an EOL change, the UNDO_SCINTILLA which changes * the line ends in the editor is followed by UNDO_EOL * which should be performed together with UNDO_SCINTILLA. */ next_action = g_trash_stack_peek(&doc->priv->redo_actions); if (next_action != NULL && next_action->type == UNDO_EOL) document_redo(doc); break; } case UNDO_BOM: { document_undo_add_internal(doc, UNDO_BOM, GINT_TO_POINTER(doc->has_bom)); doc->has_bom = GPOINTER_TO_INT(action->data); ui_update_statusbar(doc, -1); ui_document_show_hide(doc); break; } case UNDO_ENCODING: { document_undo_add_internal(doc, UNDO_ENCODING, g_strdup(doc->encoding)); document_set_encoding(doc, (const gchar*)action->data); g_free(action->data); ui_update_statusbar(doc, -1); ui_document_show_hide(doc); break; } case UNDO_EOL: { document_undo_add_internal(doc, UNDO_EOL, GINT_TO_POINTER(sci_get_eol_mode(doc->editor->sci))); sci_set_eol_mode(doc->editor->sci, GPOINTER_TO_INT(action->data)); ui_update_statusbar(doc, -1); ui_document_show_hide(doc); break; } case UNDO_RELOAD: { UndoReloadData *data = (UndoReloadData*)action->data; gint eol_mode = data->eol_mode; guint i; /* We reuse 'data' for the undo action, so read the current EOL mode * into it before proceeding. */ data->eol_mode = editor_get_eol_char_mode(doc->editor); /* Redo the rest of the actions which are part of the reloading process. */ for (i = 0; i < data->actions_count; i++) document_redo(doc); /* Restore the previous EOL mode. */ sci_set_eol_mode(doc->editor->sci, eol_mode); /* This might affect the status bar and document menu, so update them. */ ui_update_statusbar(doc, -1); ui_document_show_hide(doc); document_undo_add_internal(doc, UNDO_RELOAD, data); break; } default: break; } } g_free(action); /* free the action which was taken from the stack */ update_changed_state(doc); ui_update_popup_reundo_items(doc); } static void document_redo_add(GeanyDocument *doc, guint type, gpointer data) { undo_action *action; g_return_if_fail(doc != NULL); action = g_new0(undo_action, 1); action->type = type; action->data = data; g_trash_stack_push(&doc->priv->redo_actions, action); if (type != UNDO_SCINTILLA || !doc->changed) document_set_text_changed(doc, TRUE); ui_update_popup_reundo_items(doc); } enum { STATUS_CHANGED, STATUS_DISK_CHANGED, STATUS_READONLY }; static struct { const gchar *name; GdkColor color; gboolean loaded; } document_status_styles[] = { { "geany-document-status-changed", {0}, FALSE }, { "geany-document-status-disk-changed", {0}, FALSE }, { "geany-document-status-readonly", {0}, FALSE } }; static gint document_get_status_id(GeanyDocument *doc) { if (doc->changed) return STATUS_CHANGED; #ifdef USE_GIO_FILEMON else if (doc->priv->file_disk_status == FILE_CHANGED) #else else if (doc->priv->protected) #endif return STATUS_DISK_CHANGED; else if (doc->readonly) return STATUS_READONLY; return -1; } /* returns an identifier that is to be set as a widget name or class to get it styled * depending on the document status (changed, readonly, etc.) * a NULL return value means default (unchanged) style */ const gchar *document_get_status_widget_class(GeanyDocument *doc) { gint status; g_return_val_if_fail(doc != NULL, NULL); status = document_get_status_id(doc); if (status < 0) return NULL; else return document_status_styles[status].name; } /** * Gets the status color of the document, or @c NULL if default widget coloring should be used. * Returned colors are red if the document has changes, green if the document is read-only * or simply @c NULL if the document is unmodified but writable. * * @param doc The document to use. * * @return @nullable The color for the document or @c NULL if the default color should be used. * The color object is owned by Geany and should not be modified or freed. * * @since 0.16 */ GEANY_API_SYMBOL const GdkColor *document_get_status_color(GeanyDocument *doc) { gint status; g_return_val_if_fail(doc != NULL, NULL); status = document_get_status_id(doc); if (status < 0) return NULL; if (! document_status_styles[status].loaded) { GdkRGBA color; GtkWidgetPath *path = gtk_widget_path_new(); GtkStyleContext *ctx = gtk_style_context_new(); gtk_widget_path_append_type(path, GTK_TYPE_WINDOW); gtk_widget_path_append_type(path, GTK_TYPE_BOX); gtk_widget_path_append_type(path, GTK_TYPE_NOTEBOOK); gtk_widget_path_append_type(path, GTK_TYPE_LABEL); gtk_widget_path_iter_set_name(path, -1, document_status_styles[status].name); gtk_style_context_set_screen(ctx, gtk_widget_get_screen(GTK_WIDGET(doc->editor->sci))); gtk_style_context_set_path(ctx, path); gtk_style_context_get_color(ctx, gtk_style_context_get_state(ctx), &color); document_status_styles[status].color.red = 0xffff * color.red; document_status_styles[status].color.green = 0xffff * color.green; document_status_styles[status].color.blue = 0xffff * color.blue; document_status_styles[status].loaded = TRUE; gtk_widget_path_unref(path); g_object_unref(ctx); } return &document_status_styles[status].color; } /** Accessor function for @ref GeanyData::documents_array items. * @warning Always check the returned document is valid (@c doc->is_valid). * @param idx @c GeanyData::documents_array index. * @return @transfer{none} @nullable The document, or @c NULL if @a idx is out of range. * * @since 0.16 */ GEANY_API_SYMBOL GeanyDocument *document_index(gint idx) { return (idx >= 0 && idx < (gint) documents_array->len) ? documents[idx] : NULL; } GeanyDocument *document_clone(GeanyDocument *old_doc) { gchar *text; GeanyDocument *doc; ScintillaObject *old_sci; g_return_val_if_fail(old_doc, NULL); old_sci = old_doc->editor->sci; if (sci_has_selection(old_sci)) text = sci_get_selection_contents(old_sci); else text = sci_get_contents(old_sci, -1); doc = document_new_file(NULL, old_doc->file_type, text); g_free(text); document_set_text_changed(doc, TRUE); /* copy file properties */ doc->editor->line_wrapping = old_doc->editor->line_wrapping; doc->editor->line_breaking = old_doc->editor->line_breaking; doc->editor->auto_indent = old_doc->editor->auto_indent; editor_set_indent(doc->editor, old_doc->editor->indent_type, old_doc->editor->indent_width); doc->readonly = old_doc->readonly; doc->has_bom = old_doc->has_bom; doc->priv->protected = 0; document_set_encoding(doc, old_doc->encoding); sci_set_lines_wrapped(doc->editor->sci, doc->editor->line_wrapping); sci_set_readonly(doc->editor->sci, doc->readonly); /* update ui */ ui_document_show_hide(doc); return doc; } /* @return TRUE if all files were saved or had their changes discarded. */ gboolean document_account_for_unsaved(void) { guint p, page_count; page_count = gtk_notebook_get_n_pages(GTK_NOTEBOOK(main_widgets.notebook)); /* iterate over documents in tabs order */ for (p = 0; p < page_count; p++) { GeanyDocument *doc = document_get_from_page(p); if (DOC_VALID(doc) && doc->changed) { if (! dialogs_show_unsaved_file(doc)) return FALSE; } } return TRUE; } static void force_close_all(void) { guint i; main_status.closing_all = TRUE; foreach_document(i) { document_close(documents[i]); } main_status.closing_all = FALSE; } gboolean document_close_all(void) { if (! document_account_for_unsaved()) return FALSE; force_close_all(); return TRUE; } /* * * Shows a message related to a document. * * Use this whenever the user needs to see a document-related message, * for example when the file was externally modified or deleted. * * Any of the buttons can be @c NULL. If not @c NULL, @a btn_1's * @a response_1 response will be the default for the @c GtkInfoBar or * @c GtkDialog. * * @param doc @c GeanyDocument. * @param msgtype The type of message. * @param response_cb A callback function called when there's a response. * @param btn_1 The first action area button. * @param response_1 The response for @a btn_1. * @param btn_2 The second action area button. * @param response_2 The response for @a btn_2. * @param btn_3 The third action area button. * @param response_3 The response for @a btn_3. * @param extra_text Text to show below the main message. * @param format The text format for the main message. * @param ... Used with @a format as in @c printf. * * @since 1.25 * */ static GtkWidget* document_show_message(GeanyDocument *doc, GtkMessageType msgtype, void (*response_cb)(GtkWidget *info_bar, gint response_id, GeanyDocument *doc), const gchar *btn_1, GtkResponseType response_1, const gchar *btn_2, GtkResponseType response_2, const gchar *btn_3, GtkResponseType response_3, const gchar *extra_text, const gchar *format, ...) { va_list args; gchar *text, *markup; GtkWidget *hbox, *icon, *label, *content_area; GtkWidget *info_widget, *parent; parent = document_get_notebook_child(doc); va_start(args, format); text = g_strdup_vprintf(format, args); va_end(args); markup = g_markup_printf_escaped("%s", text); g_free(text); info_widget = gtk_info_bar_new(); /* must be done now else Gtk-WARNING: widget not within a GtkWindow */ gtk_box_pack_start(GTK_BOX(parent), info_widget, FALSE, TRUE, 0); gtk_info_bar_set_message_type(GTK_INFO_BAR(info_widget), msgtype); if (btn_1) gtk_info_bar_add_button(GTK_INFO_BAR(info_widget), btn_1, response_1); if (btn_2) gtk_info_bar_add_button(GTK_INFO_BAR(info_widget), btn_2, response_2); if (btn_3) gtk_info_bar_add_button(GTK_INFO_BAR(info_widget), btn_3, response_3); content_area = gtk_info_bar_get_content_area(GTK_INFO_BAR(info_widget)); label = geany_wrap_label_new(NULL); gtk_label_set_markup(GTK_LABEL(label), markup); g_free(markup); g_signal_connect(info_widget, "response", G_CALLBACK(response_cb), doc); hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 12); gtk_box_pack_start(GTK_BOX(content_area), hbox, TRUE, TRUE, 0); switch (msgtype) { case GTK_MESSAGE_INFO: icon = gtk_image_new_from_stock(GTK_STOCK_DIALOG_INFO, GTK_ICON_SIZE_DIALOG); break; case GTK_MESSAGE_WARNING: icon = gtk_image_new_from_stock(GTK_STOCK_DIALOG_WARNING, GTK_ICON_SIZE_DIALOG); break; case GTK_MESSAGE_QUESTION: icon = gtk_image_new_from_stock(GTK_STOCK_DIALOG_QUESTION, GTK_ICON_SIZE_DIALOG); break; case GTK_MESSAGE_ERROR: icon = gtk_image_new_from_stock(GTK_STOCK_DIALOG_ERROR, GTK_ICON_SIZE_DIALOG); break; default: icon = NULL; break; } if (icon) gtk_box_pack_start(GTK_BOX(hbox), icon, FALSE, TRUE, 0); if (extra_text) { GtkWidget *vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 6); GtkWidget *extra_label = geany_wrap_label_new(extra_text); gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(vbox), extra_label, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, TRUE, 0); } else gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0); gtk_box_reorder_child(GTK_BOX(parent), info_widget, 0); gtk_widget_show_all(info_widget); return info_widget; } static void on_monitor_reload_file_response(GtkWidget *bar, gint response_id, GeanyDocument *doc) { gboolean close = FALSE; // disable info bar so actions complete normally unprotect_document(doc); doc->priv->info_bars[MSG_TYPE_RELOAD] = NULL; if (response_id == RESPONSE_DOCUMENT_RELOAD) { close = doc->changed ? document_reload_prompt(doc, doc->encoding) : document_reload_force(doc, doc->encoding); } else if (response_id == RESPONSE_DOCUMENT_SAVE) { close = document_save_file(doc, TRUE); // force overwrite } else if (response_id == GTK_RESPONSE_CANCEL) { document_set_text_changed(doc, TRUE); close = TRUE; } if (!close) { doc->priv->info_bars[MSG_TYPE_RELOAD] = bar; protect_document(doc); return; } gtk_widget_destroy(bar); } static gboolean on_sci_key(GtkWidget *widget, GdkEventKey *event, gpointer data) { GtkInfoBar *bar = GTK_INFO_BAR(data); g_return_val_if_fail(event->type == GDK_KEY_PRESS, FALSE); switch (event->keyval) { case GDK_KEY_Tab: case GDK_KEY_ISO_Left_Tab: { GtkWidget *action_area = gtk_info_bar_get_action_area(bar); GtkDirectionType dir = event->keyval == GDK_KEY_Tab ? GTK_DIR_TAB_FORWARD : GTK_DIR_TAB_BACKWARD; gtk_widget_child_focus(action_area, dir); return TRUE; } case GDK_KEY_Escape: { gtk_info_bar_response(bar, GTK_RESPONSE_CANCEL); return TRUE; } default: return FALSE; } } /* Sets up a signal handler to intercept some keys during the lifetime of the GtkInfoBar */ static void enable_key_intercept(GeanyDocument *doc, GtkWidget *bar) { /* automatically focus editor again on bar close */ g_signal_connect_object(bar, "destroy", G_CALLBACK(gtk_widget_grab_focus), doc->editor->sci, G_CONNECT_SWAPPED); g_signal_connect_object(doc->editor->sci, "key-press-event", G_CALLBACK(on_sci_key), bar, 0); } static void monitor_reload_file(GeanyDocument *doc) { if (! doc->changed && file_prefs.reload_clean_doc_on_file_change) { document_reload_force(doc, doc->encoding); return; } gchar *base_name = g_path_get_basename(doc->file_name); /* show this message only once */ if (doc->priv->info_bars[MSG_TYPE_RELOAD] == NULL) { GtkWidget *bar; bar = document_show_message(doc, GTK_MESSAGE_QUESTION, on_monitor_reload_file_response, _("_Reload"), RESPONSE_DOCUMENT_RELOAD, _("_Overwrite"), RESPONSE_DOCUMENT_SAVE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, _("Do you want to reload it?"), _("The file '%s' on the disk is more recent than the current buffer."), base_name); protect_document(doc); doc->priv->info_bars[MSG_TYPE_RELOAD] = bar; enable_key_intercept(doc, bar); } g_free(base_name); } static void on_monitor_resave_missing_file_response(GtkWidget *bar, gint response_id, GeanyDocument *doc) { gboolean close = TRUE; unprotect_document(doc); if (response_id == RESPONSE_DOCUMENT_SAVE) close = dialogs_show_save_as(); if (close) { doc->priv->info_bars[MSG_TYPE_RESAVE] = NULL; gtk_widget_destroy(bar); } else { /* protect back the document if save didn't occur */ protect_document(doc); } } static void monitor_resave_missing_file(GeanyDocument *doc) { if (doc->priv->info_bars[MSG_TYPE_RESAVE] == NULL) { GtkWidget *bar = doc->priv->info_bars[MSG_TYPE_RELOAD]; if (bar != NULL) /* the "file on disk is newer" warning is now moot */ gtk_info_bar_response(GTK_INFO_BAR(bar), GTK_RESPONSE_CANCEL); bar = document_show_message(doc, GTK_MESSAGE_WARNING, on_monitor_resave_missing_file_response, GTK_STOCK_SAVE, RESPONSE_DOCUMENT_SAVE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL, GTK_RESPONSE_NONE, _("Try to resave the file?"), _("File \"%s\" was not found on disk!"), doc->file_name); protect_document(doc); document_set_text_changed(doc, TRUE); /* don't prompt more than once */ SETPTR(doc->real_path, NULL); doc->priv->info_bars[MSG_TYPE_RESAVE] = bar; enable_key_intercept(doc, bar); } } /* Set force to force a disk check, otherwise it is ignored if there was a check * in the last file_prefs.disk_check_timeout seconds. * @return @c TRUE if the file has changed. */ gboolean document_check_disk_status(GeanyDocument *doc, gboolean force) { gboolean ret = FALSE; gboolean use_gio_filemon; time_t mtime = 0; gchar *locale_filename; FileDiskStatus old_status; g_return_val_if_fail(doc != NULL, FALSE); /* ignore remote files and documents that have never been saved to disk */ if (notebook_switch_in_progress() || file_prefs.disk_check_timeout == 0 || doc->real_path == NULL || doc->priv->is_remote) return FALSE; use_gio_filemon = (doc->priv->monitor != NULL); if (use_gio_filemon) { if (doc->priv->file_disk_status != FILE_CHANGED && ! force) return FALSE; } else { time_t cur_time = time(NULL); if (! force && doc->priv->last_check > (cur_time - file_prefs.disk_check_timeout)) return FALSE; doc->priv->last_check = cur_time; } locale_filename = utils_get_locale_from_utf8(doc->file_name); if (!get_mtime(locale_filename, &mtime)) { monitor_resave_missing_file(doc); /* doc may be closed now */ ret = TRUE; } else if (doc->priv->mtime < mtime) { /* make sure the user is not prompted again after he cancelled the "reload file?" message */ doc->priv->mtime = mtime; monitor_reload_file(doc); /* doc may be closed now */ ret = TRUE; } g_free(locale_filename); if (DOC_VALID(doc)) { /* doc can get invalid when a document was closed */ old_status = doc->priv->file_disk_status; doc->priv->file_disk_status = FILE_OK; if (old_status != doc->priv->file_disk_status) ui_update_tab_status(doc); } return ret; } /** Compares documents by their display names. * This matches @c GCompareFunc for use with e.g. @c g_ptr_array_sort(). * @note 'Display name' means the base name of the document's filename. * * @param a @c GeanyDocument**. * @param b @c GeanyDocument**. * @warning The arguments take the address of each document pointer. * @return Negative value if a < b; zero if a = b; positive value if a > b. * * @since 0.21 */ GEANY_API_SYMBOL gint document_compare_by_display_name(gconstpointer a, gconstpointer b) { GeanyDocument *doc_a = *((GeanyDocument**) a); GeanyDocument *doc_b = *((GeanyDocument**) b); gchar *base_name_a, *base_name_b; gint result; base_name_a = g_path_get_basename(DOC_FILENAME(doc_a)); base_name_b = g_path_get_basename(DOC_FILENAME(doc_b)); result = strcmp(base_name_a, base_name_b); g_free(base_name_a); g_free(base_name_b); return result; } /** Compares documents by their tab order. * This matches @c GCompareFunc for use with e.g. @c g_ptr_array_sort(). * * @param a @c GeanyDocument**. * @param b @c GeanyDocument**. * @warning The arguments take the address of each document pointer. * @return Negative value if a < b; zero if a = b; positive value if a > b. * * @since 0.21 (GEANY_API_VERSION 209) */ GEANY_API_SYMBOL gint document_compare_by_tab_order(gconstpointer a, gconstpointer b) { GeanyDocument *doc_a = *((GeanyDocument**) a); GeanyDocument *doc_b = *((GeanyDocument**) b); gint notebook_position_doc_a; gint notebook_position_doc_b; notebook_position_doc_a = document_get_notebook_page(doc_a); notebook_position_doc_b = document_get_notebook_page(doc_b); if (notebook_position_doc_a < notebook_position_doc_b) return -1; if (notebook_position_doc_a > notebook_position_doc_b) return 1; /* equality */ return 0; } /** Compares documents by their tab order, in reverse order. * This matches @c GCompareFunc for use with e.g. @c g_ptr_array_sort(). * * @param a @c GeanyDocument**. * @param b @c GeanyDocument**. * @warning The arguments take the address of each document pointer. * @return Negative value if a < b; zero if a = b; positive value if a > b. * * @since 0.21 (GEANY_API_VERSION 209) */ GEANY_API_SYMBOL gint document_compare_by_tab_order_reverse(gconstpointer a, gconstpointer b) { return -1 * document_compare_by_tab_order(a, b); } void document_grab_focus(GeanyDocument *doc) { g_return_if_fail(doc != NULL); gtk_widget_grab_focus(GTK_WIDGET(doc->editor->sci)); } static void *copy_(void *src) { return src; } static void free_(void *doc) { } /** @gironly * Gets the GType of GeanyDocument * * @return the GeanyDocument type */ GEANY_API_SYMBOL GType document_get_type (void); G_DEFINE_BOXED_TYPE(GeanyDocument, document, copy_, free_); gpointer document_get_data(const GeanyDocument *doc, const gchar *key) { return g_datalist_get_data(&doc->priv->data, key); } void document_set_data(GeanyDocument *doc, const gchar *key, gpointer data) { g_datalist_set_data(&doc->priv->data, key, data); } void document_set_data_full(GeanyDocument *doc, const gchar *key, gpointer data, GDestroyNotify free_func) { g_datalist_set_data_full(&doc->priv->data, key, data, free_func); } geany-2.0/src/search.c0000644000175000017500000021701514514252267011615 00000000000000/* * search.c - this file is part of Geany, a fast and lightweight IDE * * Copyright 2006 The Geany contributors * * This program 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; either version 2 of the License, or * (at your option) any later version. * * This program 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /* * Find, Replace, Find in Files dialog related functions. * Note that the basic text find functions are in document.c. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include "search.h" #include "app.h" #include "dialogs.h" #include "document.h" #include "encodings.h" #include "encodingsprivate.h" #include "keyfile.h" #include "msgwindow.h" #include "prefs.h" #include "sciwrappers.h" #include "spawn.h" #include "stash.h" #include "support.h" #include "toolbar.h" #include "ui_utils.h" #include "utils.h" #include #include #include #include #include enum { GEANY_RESPONSE_FIND = 1, GEANY_RESPONSE_FIND_PREVIOUS, GEANY_RESPONSE_FIND_IN_FILE, GEANY_RESPONSE_FIND_IN_SESSION, GEANY_RESPONSE_MARK, GEANY_RESPONSE_REPLACE, GEANY_RESPONSE_REPLACE_AND_FIND, GEANY_RESPONSE_REPLACE_IN_SESSION, GEANY_RESPONSE_REPLACE_IN_FILE, GEANY_RESPONSE_REPLACE_IN_SEL }; enum { FILES_MODE_ALL, FILES_MODE_PROJECT, FILES_MODE_CUSTOM }; GeanySearchData search_data; GeanySearchPrefs search_prefs; static struct { gboolean fif_regexp; gboolean fif_case_sensitive; gboolean fif_match_whole_word; gboolean fif_invert_results; gboolean fif_recursive; gboolean fif_use_extra_options; gchar *fif_extra_options; gint fif_files_mode; gchar *fif_files; gboolean find_regexp; gboolean find_regexp_multiline; gboolean find_escape_sequences; gboolean find_case_sensitive; gboolean find_match_whole_word; gboolean find_match_word_start; gboolean find_close_dialog; gboolean replace_regexp; gboolean replace_regexp_multiline; gboolean replace_escape_sequences; gboolean replace_case_sensitive; gboolean replace_match_whole_word; gboolean replace_match_word_start; gboolean replace_search_backwards; gboolean replace_close_dialog; } settings; static StashGroup *fif_prefs = NULL; static StashGroup *find_prefs = NULL; static StashGroup *replace_prefs = NULL; static struct { GtkWidget *dialog; GtkWidget *entry; gboolean all_expanded; gint position[2]; /* x, y */ } find_dlg = {NULL, NULL, FALSE, {0, 0}}; static struct { GtkWidget *dialog; GtkWidget *find_combobox; GtkWidget *find_entry; GtkWidget *replace_combobox; GtkWidget *replace_entry; gboolean all_expanded; gint position[2]; /* x, y */ } replace_dlg = {NULL, NULL, NULL, NULL, NULL, FALSE, {0, 0}}; static struct { GtkWidget *dialog; GtkWidget *dir_combo; GtkWidget *files_combo; GtkWidget *search_combo; GtkWidget *encoding_combo; GtkWidget *files_mode_combo; gint position[2]; /* x, y */ } fif_dlg = {NULL, NULL, NULL, NULL, NULL, NULL, {0, 0}}; static void search_read_io(GString *string, GIOCondition condition, gpointer data); static void search_read_io_stderr(GString *string, GIOCondition condition, gpointer data); static void search_finished(GPid child_pid, gint status, gpointer user_data); static gchar **search_get_argv(const gchar **argv_prefix, const gchar *dir); static GRegex *compile_regex(const gchar *str, GeanyFindFlags sflags); static void on_find_replace_checkbutton_toggled(GtkToggleButton *togglebutton, gpointer user_data); static void on_find_dialog_response(GtkDialog *dialog, gint response, gpointer user_data); static void on_find_entry_activate(GtkEntry *entry, gpointer user_data); static void on_find_entry_activate_backward(GtkEntry *entry, gpointer user_data); static void on_replace_dialog_response(GtkDialog *dialog, gint response, gpointer user_data); static void on_replace_find_entry_activate(GtkEntry *entry, gpointer user_data); static void on_replace_entry_activate(GtkEntry *entry, gpointer user_data); static void on_find_in_files_dialog_response(GtkDialog *dialog, gint response, gpointer user_data); static gboolean search_find_in_files(const gchar *utf8_search_text, const gchar *dir, const gchar *opts, const gchar *enc); static void init_prefs(void) { StashGroup *group; group = stash_group_new("search"); configuration_add_pref_group(group, TRUE); stash_group_add_toggle_button(group, &search_prefs.always_wrap, "pref_search_hide_find_dialog", FALSE, "check_always_wrap_search"); stash_group_add_toggle_button(group, &search_prefs.hide_find_dialog, "pref_search_always_wrap", FALSE, "check_hide_find_dialog"); stash_group_add_toggle_button(group, &search_prefs.use_current_file_dir, "pref_search_current_file_dir", TRUE, "check_fif_current_dir"); /* dialog layout & positions */ group = stash_group_new("search"); configuration_add_session_group(group, FALSE); stash_group_add_boolean(group, &find_dlg.all_expanded, "find_all_expanded", FALSE); stash_group_add_boolean(group, &replace_dlg.all_expanded, "replace_all_expanded", FALSE); stash_group_add_integer(group, &find_dlg.position[0], "position_find_x", -1); stash_group_add_integer(group, &find_dlg.position[1], "position_find_y", -1); stash_group_add_integer(group, &replace_dlg.position[0], "position_replace_x", -1); stash_group_add_integer(group, &replace_dlg.position[1], "position_replace_y", -1); stash_group_add_integer(group, &fif_dlg.position[0], "position_fif_x", -1); stash_group_add_integer(group, &fif_dlg.position[1], "position_fif_y", -1); memset(&settings, '\0', sizeof(settings)); group = stash_group_new("search"); fif_prefs = group; configuration_add_pref_group(group, FALSE); stash_group_add_toggle_button(group, &settings.fif_regexp, "fif_regexp", FALSE, "check_regexp"); stash_group_add_toggle_button(group, &settings.fif_case_sensitive, "fif_case_sensitive", TRUE, "check_case"); stash_group_add_toggle_button(group, &settings.fif_match_whole_word, "fif_match_whole_word", FALSE, "check_wholeword"); stash_group_add_toggle_button(group, &settings.fif_invert_results, "fif_invert_results", FALSE, "check_invert"); stash_group_add_toggle_button(group, &settings.fif_recursive, "fif_recursive", FALSE, "check_recursive"); stash_group_add_entry(group, &settings.fif_extra_options, "fif_extra_options", "", "entry_extra"); stash_group_add_toggle_button(group, &settings.fif_use_extra_options, "fif_use_extra_options", FALSE, "check_extra"); stash_group_add_entry(group, &settings.fif_files, "fif_files", "", "entry_files"); stash_group_add_combo_box(group, &settings.fif_files_mode, "fif_files_mode", FILES_MODE_ALL, "combo_files_mode"); group = stash_group_new("search"); find_prefs = group; configuration_add_pref_group(group, FALSE); stash_group_add_toggle_button(group, &settings.find_regexp, "find_regexp", FALSE, "check_regexp"); stash_group_add_toggle_button(group, &settings.find_regexp_multiline, "find_regexp_multiline", FALSE, "check_multiline"); stash_group_add_toggle_button(group, &settings.find_case_sensitive, "find_case_sensitive", FALSE, "check_case"); stash_group_add_toggle_button(group, &settings.find_escape_sequences, "find_escape_sequences", FALSE, "check_escape"); stash_group_add_toggle_button(group, &settings.find_match_whole_word, "find_match_whole_word", FALSE, "check_word"); stash_group_add_toggle_button(group, &settings.find_match_word_start, "find_match_word_start", FALSE, "check_wordstart"); stash_group_add_toggle_button(group, &settings.find_close_dialog, "find_close_dialog", TRUE, "check_close"); group = stash_group_new("search"); replace_prefs = group; configuration_add_pref_group(group, FALSE); stash_group_add_toggle_button(group, &settings.replace_regexp, "replace_regexp", FALSE, "check_regexp"); stash_group_add_toggle_button(group, &settings.replace_regexp_multiline, "replace_regexp_multiline", FALSE, "check_multiline"); stash_group_add_toggle_button(group, &settings.replace_case_sensitive, "replace_case_sensitive", FALSE, "check_case"); stash_group_add_toggle_button(group, &settings.replace_escape_sequences, "replace_escape_sequences", FALSE, "check_escape"); stash_group_add_toggle_button(group, &settings.replace_match_whole_word, "replace_match_whole_word", FALSE, "check_word"); stash_group_add_toggle_button(group, &settings.replace_match_word_start, "replace_match_word_start", FALSE, "check_wordstart"); stash_group_add_toggle_button(group, &settings.replace_search_backwards, "replace_search_backwards", FALSE, "check_back"); stash_group_add_toggle_button(group, &settings.replace_close_dialog, "replace_close_dialog", TRUE, "check_close"); } void search_init(void) { search_data.text = NULL; search_data.original_text = NULL; init_prefs(); } #define FREE_WIDGET(wid) \ if (wid && GTK_IS_WIDGET(wid)) gtk_widget_destroy(wid); void search_finalize(void) { FREE_WIDGET(find_dlg.dialog); FREE_WIDGET(replace_dlg.dialog); FREE_WIDGET(fif_dlg.dialog); g_free(search_data.text); g_free(search_data.original_text); } static void on_widget_toggled_set_insensitive( GtkToggleButton *togglebutton, gpointer user_data) { gtk_widget_set_sensitive(GTK_WIDGET(user_data), !gtk_toggle_button_get_active(togglebutton)); } static GtkWidget *add_find_checkboxes(GtkDialog *dialog) { GtkWidget *checkbox1, *checkbox2, *check_regexp, *checkbox5, *checkbox7, *check_multiline, *hbox, *fbox, *mbox; check_regexp = gtk_check_button_new_with_mnemonic(_("_Use regular expressions")); ui_hookup_widget(dialog, check_regexp, "check_regexp"); gtk_button_set_focus_on_click(GTK_BUTTON(check_regexp), FALSE); gtk_widget_set_tooltip_text(check_regexp, _("Use Perl-like regular expressions. " "For detailed information about using regular expressions, please refer to the manual.")); g_signal_connect(check_regexp, "toggled", G_CALLBACK(on_find_replace_checkbutton_toggled), dialog); checkbox7 = gtk_check_button_new_with_mnemonic(_("Use _escape sequences")); ui_hookup_widget(dialog, checkbox7, "check_escape"); gtk_button_set_focus_on_click(GTK_BUTTON(checkbox7), FALSE); gtk_widget_set_tooltip_text(checkbox7, _("Replace \\\\, \\t, \\n, \\r and \\uXXXX (Unicode characters) with the " "corresponding control characters")); check_multiline = gtk_check_button_new_with_mnemonic(_("Use multi-line matchin_g")); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_multiline), FALSE); gtk_widget_set_sensitive(check_multiline, FALSE); ui_hookup_widget(dialog, check_multiline, "check_multiline"); gtk_button_set_focus_on_click(GTK_BUTTON(check_multiline), FALSE); gtk_widget_set_tooltip_text(check_multiline, _("Perform regular expression " "matching on the whole buffer at once rather than line by line, allowing " "matches to span multiple lines. In this mode, newline characters are part " "of the input and can be captured as normal characters by the pattern.")); /* Search features */ fbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); gtk_box_pack_start(GTK_BOX(fbox), check_regexp, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(fbox), check_multiline, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(fbox), checkbox7, FALSE, FALSE, 0); if (dialog != GTK_DIALOG(find_dlg.dialog)) { GtkWidget *check_back = gtk_check_button_new_with_mnemonic(_("Search _backwards")); ui_hookup_widget(dialog, check_back, "check_back"); gtk_button_set_focus_on_click(GTK_BUTTON(check_back), FALSE); gtk_container_add(GTK_CONTAINER(fbox), check_back); } checkbox1 = gtk_check_button_new_with_mnemonic(_("C_ase sensitive")); ui_hookup_widget(dialog, checkbox1, "check_case"); gtk_button_set_focus_on_click(GTK_BUTTON(checkbox1), FALSE); checkbox2 = gtk_check_button_new_with_mnemonic(_("Match only a _whole word")); ui_hookup_widget(dialog, checkbox2, "check_word"); gtk_button_set_focus_on_click(GTK_BUTTON(checkbox2), FALSE); checkbox5 = gtk_check_button_new_with_mnemonic(_("Match from s_tart of word")); ui_hookup_widget(dialog, checkbox5, "check_wordstart"); gtk_button_set_focus_on_click(GTK_BUTTON(checkbox5), FALSE); /* disable wordstart when wholeword is checked */ g_signal_connect(checkbox2, "toggled", G_CALLBACK(on_widget_toggled_set_insensitive), checkbox5); /* Matching options */ mbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); gtk_box_pack_start(GTK_BOX(mbox), checkbox1, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(mbox), checkbox2, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(mbox), checkbox5, FALSE, FALSE, 0); hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6); gtk_box_set_homogeneous(GTK_BOX(hbox), TRUE); gtk_container_add(GTK_CONTAINER(hbox), fbox); gtk_container_add(GTK_CONTAINER(hbox), mbox); return hbox; } static void send_find_dialog_response(GtkButton *button, gpointer user_data) { gtk_dialog_response(GTK_DIALOG(find_dlg.dialog), GPOINTER_TO_INT(user_data)); } /* store text, clear search flags so we can use Search->Find Next/Previous */ static void setup_find_next(const gchar *text) { g_free(search_data.text); g_free(search_data.original_text); search_data.text = g_strdup(text); search_data.original_text = g_strdup(text); search_data.flags = 0; search_data.backwards = FALSE; search_data.search_bar = FALSE; } /* Search for next match of the current "selection". * Optionally for X11 based systems, this will try to use the system-wide * x-selection first. * If it doesn't find a suitable search string it will try to use * the current word instead, or just repeat the last search. * Search flags are always zero. */ void search_find_selection(GeanyDocument *doc, gboolean search_backwards) { gchar *s = NULL; g_return_if_fail(DOC_VALID(doc)); #ifdef G_OS_UNIX if (search_prefs.find_selection_type == GEANY_FIND_SEL_X) { GtkClipboard *clipboard = gtk_clipboard_get(GDK_SELECTION_PRIMARY); s = gtk_clipboard_wait_for_text(clipboard); if (s && (strchr(s,'\n') || strchr(s, '\r'))) { g_free(s); s = NULL; }; } #endif if (!s && sci_has_selection(doc->editor->sci)) s = sci_get_selection_contents(doc->editor->sci); if (!s && search_prefs.find_selection_type != GEANY_FIND_SEL_AGAIN) { /* get the current word */ s = editor_get_default_selection(doc->editor, TRUE, NULL); } if (s) { setup_find_next(s); /* allow find next/prev */ if (document_find_text(doc, s, NULL, 0, search_backwards, NULL, FALSE, NULL) > -1) editor_display_current_line(doc->editor, 0.3F); g_free(s); } else if (search_prefs.find_selection_type == GEANY_FIND_SEL_AGAIN) { /* Repeat last search (in case selection was lost) */ search_find_again(search_backwards); } else { utils_beep(); } } static void on_expander_activated(GtkExpander *exp, gpointer data) { gboolean *setting = data; *setting = gtk_expander_get_expanded(exp); } static void create_find_dialog(void) { GtkWidget *label, *entry, *sbox, *vbox; GtkWidget *exp, *bbox, *button, *check_close; find_dlg.dialog = gtk_dialog_new_with_buttons(_("Find"), GTK_WINDOW(main_widgets.window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_CLOSE, GTK_RESPONSE_CANCEL, NULL); vbox = ui_dialog_vbox_new(GTK_DIALOG(find_dlg.dialog)); gtk_widget_set_name(find_dlg.dialog, "GeanyDialogSearch"); gtk_box_set_spacing(GTK_BOX(vbox), 9); button = ui_button_new_with_image(GTK_STOCK_GO_BACK, _("_Previous")); gtk_dialog_add_action_widget(GTK_DIALOG(find_dlg.dialog), button, GEANY_RESPONSE_FIND_PREVIOUS); ui_hookup_widget(find_dlg.dialog, button, "btn_previous"); button = ui_button_new_with_image(GTK_STOCK_GO_FORWARD, _("_Next")); gtk_dialog_add_action_widget(GTK_DIALOG(find_dlg.dialog), button, GEANY_RESPONSE_FIND); label = gtk_label_new_with_mnemonic(_("_Search for:")); gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); entry = gtk_combo_box_text_new_with_entry(); ui_entry_add_clear_icon(GTK_ENTRY(gtk_bin_get_child(GTK_BIN(entry)))); gtk_label_set_mnemonic_widget(GTK_LABEL(label), entry); gtk_entry_set_width_chars(GTK_ENTRY(gtk_bin_get_child(GTK_BIN(entry))), 50); find_dlg.entry = gtk_bin_get_child(GTK_BIN(entry)); g_signal_connect(gtk_bin_get_child(GTK_BIN(entry)), "activate", G_CALLBACK(on_find_entry_activate), entry); ui_entry_add_activate_backward_signal(GTK_ENTRY(gtk_bin_get_child(GTK_BIN(entry)))); g_signal_connect(gtk_bin_get_child(GTK_BIN(entry)), "activate-backward", G_CALLBACK(on_find_entry_activate_backward), entry); g_signal_connect(find_dlg.dialog, "response", G_CALLBACK(on_find_dialog_response), entry); g_signal_connect(find_dlg.dialog, "delete-event", G_CALLBACK(gtk_widget_hide_on_delete), NULL); sbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6); gtk_box_pack_start(GTK_BOX(sbox), label, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(sbox), entry, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(vbox), sbox, TRUE, FALSE, 0); gtk_container_add(GTK_CONTAINER(vbox), add_find_checkboxes(GTK_DIALOG(find_dlg.dialog))); /* Now add the multiple match options */ exp = gtk_expander_new_with_mnemonic(_("_Find All")); gtk_expander_set_expanded(GTK_EXPANDER(exp), find_dlg.all_expanded); g_signal_connect_after(exp, "activate", G_CALLBACK(on_expander_activated), &find_dlg.all_expanded); bbox = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL); button = gtk_button_new_with_mnemonic(_("_Mark")); gtk_widget_set_tooltip_text(button, _("Mark all matches in the current document")); gtk_container_add(GTK_CONTAINER(bbox), button); g_signal_connect(button, "clicked", G_CALLBACK(send_find_dialog_response), GINT_TO_POINTER(GEANY_RESPONSE_MARK)); button = gtk_button_new_with_mnemonic(_("In Sessi_on")); gtk_container_add(GTK_CONTAINER(bbox), button); g_signal_connect(button, "clicked", G_CALLBACK(send_find_dialog_response), GINT_TO_POINTER(GEANY_RESPONSE_FIND_IN_SESSION)); button = gtk_button_new_with_mnemonic(_("_In Document")); gtk_container_add(GTK_CONTAINER(bbox), button); g_signal_connect(button, "clicked", G_CALLBACK(send_find_dialog_response), GINT_TO_POINTER(GEANY_RESPONSE_FIND_IN_FILE)); /* close window checkbox */ check_close = gtk_check_button_new_with_mnemonic(_("Close _dialog")); ui_hookup_widget(find_dlg.dialog, check_close, "check_close"); gtk_button_set_focus_on_click(GTK_BUTTON(check_close), FALSE); gtk_widget_set_tooltip_text(check_close, _("Disable this option to keep the dialog open")); gtk_container_add(GTK_CONTAINER(bbox), check_close); gtk_button_box_set_child_secondary(GTK_BUTTON_BOX(bbox), check_close, TRUE); ui_hbutton_box_copy_layout( GTK_BUTTON_BOX(gtk_dialog_get_action_area(GTK_DIALOG(find_dlg.dialog))), GTK_BUTTON_BOX(bbox)); gtk_container_add(GTK_CONTAINER(exp), bbox); gtk_container_add(GTK_CONTAINER(vbox), exp); } static void set_dialog_position(GtkWidget *dialog, gint *position) { if (position[0] >= 0) gtk_window_move(GTK_WINDOW(dialog), position[0], position[1]); } void search_show_find_dialog(void) { GeanyDocument *doc = document_get_current(); gchar *sel = NULL; g_return_if_fail(doc != NULL); sel = editor_get_default_selection(doc->editor, search_prefs.use_current_word, NULL); if (find_dlg.dialog == NULL) { create_find_dialog(); stash_group_display(find_prefs, find_dlg.dialog); if (sel) gtk_entry_set_text(GTK_ENTRY(find_dlg.entry), sel); set_dialog_position(find_dlg.dialog, find_dlg.position); gtk_widget_show_all(find_dlg.dialog); } else { if (sel != NULL) { /* update the search text from current selection */ gtk_entry_set_text(GTK_ENTRY(find_dlg.entry), sel); /* reset the entry widget's background colour */ ui_set_search_entry_background(find_dlg.entry, TRUE); } gtk_widget_grab_focus(find_dlg.entry); set_dialog_position(find_dlg.dialog, find_dlg.position); gtk_widget_show(find_dlg.dialog); /* bring the dialog back in the foreground in case it is already open but the focus is away */ gtk_window_present(GTK_WINDOW(find_dlg.dialog)); } g_free(sel); } static void send_replace_dialog_response(GtkButton *button, gpointer user_data) { gtk_dialog_response(GTK_DIALOG(replace_dlg.dialog), GPOINTER_TO_INT(user_data)); } static gboolean on_widget_key_pressed_set_focus(GtkWidget *widget, GdkEventKey *event, gpointer user_data) { if (event->keyval == GDK_KEY_Tab) { gtk_widget_grab_focus(GTK_WIDGET(user_data)); return TRUE; } return FALSE; } static void create_replace_dialog(void) { GtkWidget *label_find, *label_replace, *check_close, *button, *rbox, *fbox, *vbox, *exp, *bbox; GtkSizeGroup *label_size; replace_dlg.dialog = gtk_dialog_new_with_buttons(_("Replace"), GTK_WINDOW(main_widgets.window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_CLOSE, GTK_RESPONSE_CANCEL, NULL); vbox = ui_dialog_vbox_new(GTK_DIALOG(replace_dlg.dialog)); gtk_box_set_spacing(GTK_BOX(vbox), 9); gtk_widget_set_name(replace_dlg.dialog, "GeanyDialogSearch"); button = gtk_button_new_from_stock(GTK_STOCK_FIND); gtk_dialog_add_action_widget(GTK_DIALOG(replace_dlg.dialog), button, GEANY_RESPONSE_FIND); button = gtk_button_new_with_mnemonic(_("_Replace")); gtk_button_set_image(GTK_BUTTON(button), gtk_image_new_from_stock(GTK_STOCK_FIND_AND_REPLACE, GTK_ICON_SIZE_BUTTON)); gtk_dialog_add_action_widget(GTK_DIALOG(replace_dlg.dialog), button, GEANY_RESPONSE_REPLACE); button = gtk_button_new_with_mnemonic(_("Replace & Fi_nd")); gtk_button_set_image(GTK_BUTTON(button), gtk_image_new_from_stock(GTK_STOCK_FIND_AND_REPLACE, GTK_ICON_SIZE_BUTTON)); gtk_dialog_add_action_widget(GTK_DIALOG(replace_dlg.dialog), button, GEANY_RESPONSE_REPLACE_AND_FIND); label_find = gtk_label_new_with_mnemonic(_("_Search for:")); gtk_misc_set_alignment(GTK_MISC(label_find), 0, 0.5); label_replace = gtk_label_new_with_mnemonic(_("Replace wit_h:")); gtk_misc_set_alignment(GTK_MISC(label_replace), 0, 0.5); replace_dlg.find_combobox = gtk_combo_box_text_new_with_entry(); replace_dlg.find_entry = gtk_bin_get_child(GTK_BIN(replace_dlg.find_combobox)); ui_entry_add_clear_icon(GTK_ENTRY(replace_dlg.find_entry)); gtk_label_set_mnemonic_widget(GTK_LABEL(label_find), replace_dlg.find_combobox); gtk_entry_set_width_chars(GTK_ENTRY(replace_dlg.find_entry), 50); ui_hookup_widget(replace_dlg.dialog, replace_dlg.find_combobox, "entry_find"); replace_dlg.replace_combobox = gtk_combo_box_text_new_with_entry(); replace_dlg.replace_entry = gtk_bin_get_child(GTK_BIN(replace_dlg.replace_combobox)); ui_entry_add_clear_icon(GTK_ENTRY(replace_dlg.replace_entry)); gtk_label_set_mnemonic_widget(GTK_LABEL(label_replace), replace_dlg.replace_combobox); gtk_entry_set_width_chars(GTK_ENTRY(replace_dlg.replace_entry), 50); ui_hookup_widget(replace_dlg.dialog, replace_dlg.replace_combobox, "entry_replace"); /* tab from find to the replace entry */ g_signal_connect(replace_dlg.find_entry, "key-press-event", G_CALLBACK(on_widget_key_pressed_set_focus), replace_dlg.replace_entry); g_signal_connect(replace_dlg.find_entry, "activate", G_CALLBACK(on_replace_find_entry_activate), NULL); g_signal_connect(replace_dlg.replace_entry, "activate", G_CALLBACK(on_replace_entry_activate), NULL); g_signal_connect(replace_dlg.dialog, "response", G_CALLBACK(on_replace_dialog_response), NULL); g_signal_connect(replace_dlg.dialog, "delete-event", G_CALLBACK(gtk_widget_hide_on_delete), NULL); fbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6); gtk_box_pack_start(GTK_BOX(fbox), label_find, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(fbox), replace_dlg.find_combobox, TRUE, TRUE, 0); rbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6); gtk_box_pack_start(GTK_BOX(rbox), label_replace, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(rbox), replace_dlg.replace_combobox, TRUE, TRUE, 0); label_size = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); gtk_size_group_add_widget(label_size, label_find); gtk_size_group_add_widget(label_size, label_replace); g_object_unref(G_OBJECT(label_size)); /* auto destroy the size group */ gtk_box_pack_start(GTK_BOX(vbox), fbox, TRUE, FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox), rbox, TRUE, FALSE, 0); gtk_container_add(GTK_CONTAINER(vbox), add_find_checkboxes(GTK_DIALOG(replace_dlg.dialog))); /* Now add the multiple replace options */ exp = gtk_expander_new_with_mnemonic(_("Re_place All")); gtk_expander_set_expanded(GTK_EXPANDER(exp), replace_dlg.all_expanded); g_signal_connect_after(exp, "activate", G_CALLBACK(on_expander_activated), &replace_dlg.all_expanded); bbox = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL); button = gtk_button_new_with_mnemonic(_("In Sessi_on")); gtk_container_add(GTK_CONTAINER(bbox), button); g_signal_connect(button, "clicked", G_CALLBACK(send_replace_dialog_response), GINT_TO_POINTER(GEANY_RESPONSE_REPLACE_IN_SESSION)); button = gtk_button_new_with_mnemonic(_("_In Document")); gtk_container_add(GTK_CONTAINER(bbox), button); g_signal_connect(button, "clicked", G_CALLBACK(send_replace_dialog_response), GINT_TO_POINTER(GEANY_RESPONSE_REPLACE_IN_FILE)); button = gtk_button_new_with_mnemonic(_("In Se_lection")); gtk_widget_set_tooltip_text(button, _("Replace all matches found in the currently selected text")); gtk_container_add(GTK_CONTAINER(bbox), button); g_signal_connect(button, "clicked", G_CALLBACK(send_replace_dialog_response), GINT_TO_POINTER(GEANY_RESPONSE_REPLACE_IN_SEL)); /* close window checkbox */ check_close = gtk_check_button_new_with_mnemonic(_("Close _dialog")); ui_hookup_widget(replace_dlg.dialog, check_close, "check_close"); gtk_button_set_focus_on_click(GTK_BUTTON(check_close), FALSE); gtk_widget_set_tooltip_text(check_close, _("Disable this option to keep the dialog open")); gtk_container_add(GTK_CONTAINER(bbox), check_close); gtk_button_box_set_child_secondary(GTK_BUTTON_BOX(bbox), check_close, TRUE); ui_hbutton_box_copy_layout( GTK_BUTTON_BOX(gtk_dialog_get_action_area(GTK_DIALOG(replace_dlg.dialog))), GTK_BUTTON_BOX(bbox)); gtk_container_add(GTK_CONTAINER(exp), bbox); gtk_container_add(GTK_CONTAINER(vbox), exp); } void search_show_replace_dialog(void) { GeanyDocument *doc = document_get_current(); gchar *sel = NULL; if (doc == NULL) return; sel = editor_get_default_selection(doc->editor, search_prefs.use_current_word, NULL); if (replace_dlg.dialog == NULL) { create_replace_dialog(); stash_group_display(replace_prefs, replace_dlg.dialog); if (sel) gtk_entry_set_text(GTK_ENTRY(replace_dlg.find_entry), sel); set_dialog_position(replace_dlg.dialog, replace_dlg.position); gtk_widget_show_all(replace_dlg.dialog); } else { if (sel != NULL) { /* update the search text from current selection */ gtk_entry_set_text(GTK_ENTRY(replace_dlg.find_entry), sel); /* reset the entry widget's background colour */ ui_set_search_entry_background(replace_dlg.find_entry, TRUE); } gtk_widget_grab_focus(replace_dlg.find_entry); set_dialog_position(replace_dlg.dialog, replace_dlg.position); gtk_widget_show(replace_dlg.dialog); /* bring the dialog back in the foreground in case it is already open but the focus is away */ gtk_window_present(GTK_WINDOW(replace_dlg.dialog)); } g_free(sel); } static void on_widget_toggled_set_sensitive(GtkToggleButton *togglebutton, gpointer user_data) { /* disable extra option entry when checkbutton not checked */ gtk_widget_set_sensitive(GTK_WIDGET(user_data), gtk_toggle_button_get_active(togglebutton)); } static void update_file_patterns(GtkWidget *mode_combo, GtkWidget *fcombo) { gint selection; GtkWidget *entry; entry = gtk_bin_get_child(GTK_BIN(fcombo)); selection = gtk_combo_box_get_active(GTK_COMBO_BOX(mode_combo)); if (selection == FILES_MODE_ALL) { gtk_entry_set_text(GTK_ENTRY(entry), ""); gtk_widget_set_sensitive(fcombo, FALSE); } else if (selection == FILES_MODE_CUSTOM) { gtk_widget_set_sensitive(fcombo, TRUE); } else if (selection == FILES_MODE_PROJECT) { if (app->project && !EMPTY(app->project->file_patterns)) { gchar *patterns; patterns = g_strjoinv(" ", app->project->file_patterns); gtk_entry_set_text(GTK_ENTRY(entry), patterns); g_free(patterns); } else { gtk_entry_set_text(GTK_ENTRY(entry), ""); } gtk_widget_set_sensitive(fcombo, FALSE); } } /* creates the combo to choose which files include in the search */ static GtkWidget *create_fif_file_mode_combo(void) { GtkWidget *combo; GtkCellRenderer *renderer; GtkListStore *store; GtkTreeIter iter; /* text/sensitive */ store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_BOOLEAN); gtk_list_store_append(store, &iter); gtk_list_store_set(store, &iter, 0, _("all"), 1, TRUE, -1); gtk_list_store_append(store, &iter); gtk_list_store_set(store, &iter, 0, _("project"), 1, app->project != NULL, -1); gtk_list_store_append(store, &iter); gtk_list_store_set(store, &iter, 0, _("custom"), 1, TRUE, -1); combo = gtk_combo_box_new_with_model(GTK_TREE_MODEL(store)); g_object_unref(store); gtk_widget_set_tooltip_text(combo, _("All: search all files in the directory\n" "Project: use file patterns defined in the project settings\n" "Custom: specify file patterns manually")); renderer = gtk_cell_renderer_text_new(); gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combo), renderer, TRUE); gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combo), renderer, "text", 0, "sensitive", 1, NULL); return combo; } /* updates the sensitivity of the project combo item */ static void update_fif_file_mode_combo(void) { GtkTreeModel *model = gtk_combo_box_get_model(GTK_COMBO_BOX(fif_dlg.files_mode_combo)); GtkTreeIter iter; /* "1" refers to the second list entry, project */ if (gtk_tree_model_get_iter_from_string(model, &iter, "1")) gtk_list_store_set(GTK_LIST_STORE(model), &iter, 1, app->project != NULL, -1); } static void create_fif_dialog(void) { GtkWidget *dir_combo, *combo, *fcombo, *e_combo, *entry; GtkWidget *label, *label1, *label2, *label3, *checkbox1, *checkbox2, *check_wholeword, *check_recursive, *check_extra, *entry_extra, *check_regexp, *combo_files_mode; GtkWidget *dbox, *sbox, *lbox, *rbox, *hbox, *vbox, *ebox; GtkSizeGroup *size_group; fif_dlg.dialog = gtk_dialog_new_with_buttons( _("Find in Files"), GTK_WINDOW(main_widgets.window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL); vbox = ui_dialog_vbox_new(GTK_DIALOG(fif_dlg.dialog)); gtk_box_set_spacing(GTK_BOX(vbox), 9); gtk_widget_set_name(fif_dlg.dialog, "GeanyDialogSearch"); gtk_dialog_add_button(GTK_DIALOG(fif_dlg.dialog), GTK_STOCK_FIND, GTK_RESPONSE_ACCEPT); gtk_dialog_set_default_response(GTK_DIALOG(fif_dlg.dialog), GTK_RESPONSE_ACCEPT); label = gtk_label_new_with_mnemonic(_("_Search for:")); gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); combo = gtk_combo_box_text_new_with_entry(); entry = gtk_bin_get_child(GTK_BIN(combo)); ui_entry_add_clear_icon(GTK_ENTRY(entry)); gtk_label_set_mnemonic_widget(GTK_LABEL(label), entry); gtk_entry_set_width_chars(GTK_ENTRY(entry), 50); gtk_entry_set_activates_default(GTK_ENTRY(entry), TRUE); fif_dlg.search_combo = combo; sbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6); gtk_box_pack_start(GTK_BOX(sbox), label, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(sbox), combo, TRUE, TRUE, 0); /* make labels same width */ size_group = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); gtk_size_group_add_widget(size_group, label); label3 = gtk_label_new_with_mnemonic(_("File _patterns:")); gtk_misc_set_alignment(GTK_MISC(label3), 0, 0.5); combo_files_mode = create_fif_file_mode_combo(); gtk_label_set_mnemonic_widget(GTK_LABEL(label3), combo_files_mode); ui_hookup_widget(fif_dlg.dialog, combo_files_mode, "combo_files_mode"); fif_dlg.files_mode_combo = combo_files_mode; fcombo = gtk_combo_box_text_new_with_entry(); entry = gtk_bin_get_child(GTK_BIN(fcombo)); ui_entry_add_clear_icon(GTK_ENTRY(entry)); gtk_entry_set_activates_default(GTK_ENTRY(entry), TRUE); gtk_widget_set_tooltip_text(entry, _("Space separated list of file patterns (e.g. *.c *.h)")); ui_hookup_widget(fif_dlg.dialog, entry, "entry_files"); fif_dlg.files_combo = fcombo; /* update the entry when selection is changed */ g_signal_connect(combo_files_mode, "changed", G_CALLBACK(update_file_patterns), fcombo); hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6); gtk_box_pack_start(GTK_BOX(hbox), label3, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox), combo_files_mode, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox), fcombo, TRUE, TRUE, 0); label1 = gtk_label_new_with_mnemonic(_("_Directory:")); gtk_misc_set_alignment(GTK_MISC(label1), 0, 0.5); dir_combo = gtk_combo_box_text_new_with_entry(); entry = gtk_bin_get_child(GTK_BIN(dir_combo)); ui_entry_add_clear_icon(GTK_ENTRY(entry)); gtk_entry_set_activates_default(GTK_ENTRY(entry), TRUE); gtk_label_set_mnemonic_widget(GTK_LABEL(label1), entry); gtk_entry_set_width_chars(GTK_ENTRY(entry), 50); fif_dlg.dir_combo = dir_combo; /* tab from files to the dir entry */ g_signal_connect(gtk_bin_get_child(GTK_BIN(fcombo)), "key-press-event", G_CALLBACK(on_widget_key_pressed_set_focus), entry); dbox = ui_path_box_new(NULL, GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, GTK_ENTRY(entry)); gtk_box_pack_start(GTK_BOX(dbox), label1, FALSE, FALSE, 0); label2 = gtk_label_new_with_mnemonic(_("E_ncoding:")); gtk_misc_set_alignment(GTK_MISC(label2), 0, 0.5); e_combo = ui_create_encodings_combo_box(FALSE, GEANY_ENCODING_UTF_8); gtk_label_set_mnemonic_widget(GTK_LABEL(label2), e_combo); fif_dlg.encoding_combo = e_combo; ebox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6); gtk_box_pack_start(GTK_BOX(ebox), label2, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(ebox), e_combo, TRUE, TRUE, 0); gtk_size_group_add_widget(size_group, label1); gtk_size_group_add_widget(size_group, label2); gtk_size_group_add_widget(size_group, label3); g_object_unref(G_OBJECT(size_group)); /* auto destroy the size group */ gtk_box_pack_start(GTK_BOX(vbox), sbox, TRUE, FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox), dbox, TRUE, FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox), ebox, TRUE, FALSE, 0); check_regexp = gtk_check_button_new_with_mnemonic(_("_Use regular expressions")); ui_hookup_widget(fif_dlg.dialog, check_regexp, "check_regexp"); gtk_button_set_focus_on_click(GTK_BUTTON(check_regexp), FALSE); gtk_widget_set_tooltip_text(check_regexp, _("See grep's manual page for more information")); check_recursive = gtk_check_button_new_with_mnemonic(_("_Recurse in subfolders")); ui_hookup_widget(fif_dlg.dialog, check_recursive, "check_recursive"); gtk_button_set_focus_on_click(GTK_BUTTON(check_recursive), FALSE); checkbox1 = gtk_check_button_new_with_mnemonic(_("C_ase sensitive")); ui_hookup_widget(fif_dlg.dialog, checkbox1, "check_case"); gtk_button_set_focus_on_click(GTK_BUTTON(checkbox1), FALSE); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbox1), TRUE); check_wholeword = gtk_check_button_new_with_mnemonic(_("Match only a _whole word")); ui_hookup_widget(fif_dlg.dialog, check_wholeword, "check_wholeword"); gtk_button_set_focus_on_click(GTK_BUTTON(check_wholeword), FALSE); checkbox2 = gtk_check_button_new_with_mnemonic(_("_Invert search results")); ui_hookup_widget(fif_dlg.dialog, checkbox2, "check_invert"); gtk_button_set_focus_on_click(GTK_BUTTON(checkbox2), FALSE); gtk_widget_set_tooltip_text(checkbox2, _("Invert the sense of matching, to select non-matching lines")); lbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); gtk_container_add(GTK_CONTAINER(lbox), check_regexp); gtk_container_add(GTK_CONTAINER(lbox), checkbox2); gtk_container_add(GTK_CONTAINER(lbox), check_recursive); rbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); gtk_container_add(GTK_CONTAINER(rbox), checkbox1); gtk_container_add(GTK_CONTAINER(rbox), check_wholeword); gtk_container_add(GTK_CONTAINER(rbox), gtk_label_new(NULL)); hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6); gtk_container_add(GTK_CONTAINER(hbox), lbox); gtk_container_add(GTK_CONTAINER(hbox), rbox); gtk_container_add(GTK_CONTAINER(vbox), hbox); check_extra = gtk_check_button_new_with_mnemonic(_("E_xtra options:")); ui_hookup_widget(fif_dlg.dialog, check_extra, "check_extra"); gtk_button_set_focus_on_click(GTK_BUTTON(check_extra), FALSE); entry_extra = gtk_entry_new(); ui_entry_add_clear_icon(GTK_ENTRY(entry_extra)); gtk_entry_set_activates_default(GTK_ENTRY(entry_extra), TRUE); gtk_widget_set_sensitive(entry_extra, FALSE); gtk_widget_set_tooltip_text(entry_extra, _("Other options to pass to Grep")); ui_hookup_widget(fif_dlg.dialog, entry_extra, "entry_extra"); /* enable entry_extra when check_extra is checked */ g_signal_connect(check_extra, "toggled", G_CALLBACK(on_widget_toggled_set_sensitive), entry_extra); hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6); gtk_box_pack_start(GTK_BOX(hbox), check_extra, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox), entry_extra, TRUE, TRUE, 0); gtk_container_add(GTK_CONTAINER(vbox), hbox); g_signal_connect(fif_dlg.dialog, "response", G_CALLBACK(on_find_in_files_dialog_response), NULL); g_signal_connect(fif_dlg.dialog, "delete-event", G_CALLBACK(gtk_widget_hide_on_delete), NULL); } /** * Shows the Find in Files dialog. * * @param dir The directory to search in (UTF-8 encoding). May be @c NULL * to determine it the usual way by using the current document's path. * * @since 0.14, plugin API 53 */ GEANY_API_SYMBOL void search_show_find_in_files_dialog(const gchar *dir) { search_show_find_in_files_dialog_full(NULL, dir); } void search_show_find_in_files_dialog_full(const gchar *text, const gchar *dir) { GtkWidget *entry; /* for child GtkEntry of a GtkComboBoxEntry */ GeanyDocument *doc = document_get_current(); gchar *sel = NULL; gchar *cur_dir = NULL; GeanyEncodingIndex enc_idx = GEANY_ENCODING_UTF_8; if (fif_dlg.dialog == NULL) { create_fif_dialog(); gtk_widget_show_all(fif_dlg.dialog); if (doc && !text) sel = editor_get_default_selection(doc->editor, search_prefs.use_current_word, NULL); } stash_group_display(fif_prefs, fif_dlg.dialog); if (!text) { if (doc && ! sel) sel = editor_get_default_selection(doc->editor, search_prefs.use_current_word, NULL); text = sel; } entry = gtk_bin_get_child(GTK_BIN(fif_dlg.search_combo)); if (text) gtk_entry_set_text(GTK_ENTRY(entry), text); g_free(sel); /* add project's base path directory to the dir list, we do this here once * (in create_fif_dialog() it would fail if a project is opened after dialog creation) */ if (app->project != NULL && !EMPTY(app->project->base_path)) { ui_combo_box_prepend_text_once(GTK_COMBO_BOX_TEXT(fif_dlg.dir_combo), app->project->base_path); } entry = gtk_bin_get_child(GTK_BIN(fif_dlg.dir_combo)); if (!EMPTY(dir)) cur_dir = g_strdup(dir); /* custom directory argument passed */ else { if (search_prefs.use_current_file_dir) { static gchar *last_cur_dir = NULL; static GeanyDocument *last_doc = NULL; /* Only set the directory entry once for the current document */ cur_dir = utils_get_current_file_dir_utf8(); if (doc == last_doc && cur_dir && utils_str_equal(cur_dir, last_cur_dir)) { /* in case the user now wants the current directory, add it to history */ ui_combo_box_add_to_history(GTK_COMBO_BOX_TEXT(fif_dlg.dir_combo), cur_dir, 0); SETPTR(cur_dir, NULL); } else SETPTR(last_cur_dir, g_strdup(cur_dir)); last_doc = doc; } if (!cur_dir && EMPTY(gtk_entry_get_text(GTK_ENTRY(entry)))) { /* use default_open_path if no directory could be determined * (e.g. when no files are open) */ if (!cur_dir) cur_dir = g_strdup(utils_get_default_dir_utf8()); if (!cur_dir) cur_dir = g_get_current_dir(); } } if (cur_dir) { gtk_entry_set_text(GTK_ENTRY(entry), cur_dir); g_free(cur_dir); } update_fif_file_mode_combo(); update_file_patterns(fif_dlg.files_mode_combo, fif_dlg.files_combo); /* set the encoding of the current file */ if (doc != NULL) enc_idx = encodings_get_idx_from_charset(doc->encoding); ui_encodings_combo_box_set_active_encoding(GTK_COMBO_BOX(fif_dlg.encoding_combo), enc_idx); /* put the focus to the directory entry if it is empty */ if (utils_str_equal(gtk_entry_get_text(GTK_ENTRY(entry)), "")) gtk_widget_grab_focus(fif_dlg.dir_combo); else gtk_widget_grab_focus(fif_dlg.search_combo); /* set dialog window position */ set_dialog_position(fif_dlg.dialog, fif_dlg.position); gtk_widget_show(fif_dlg.dialog); /* bring the dialog back in the foreground in case it is already open but the focus is away */ gtk_window_present(GTK_WINDOW(fif_dlg.dialog)); } static void on_find_replace_checkbutton_toggled(GtkToggleButton *togglebutton, gpointer user_data) { GtkWidget *dialog = GTK_WIDGET(user_data); GtkToggleButton *chk_regexp = GTK_TOGGLE_BUTTON( ui_lookup_widget(dialog, "check_regexp")); if (togglebutton == chk_regexp) { gboolean regex_set = gtk_toggle_button_get_active(chk_regexp); GtkWidget *check_word = ui_lookup_widget(dialog, "check_word"); GtkWidget *check_wordstart = ui_lookup_widget(dialog, "check_wordstart"); GtkWidget *check_escape = ui_lookup_widget(dialog, "check_escape"); GtkWidget *check_multiline = ui_lookup_widget(dialog, "check_multiline"); gboolean replace = (dialog != find_dlg.dialog); const char *back_button[2] = { "btn_previous" , "check_back" }; /* hide options that don't apply to regex searches */ gtk_widget_set_sensitive(check_escape, ! regex_set); gtk_widget_set_sensitive(ui_lookup_widget(dialog, back_button[replace]), ! regex_set); gtk_widget_set_sensitive(check_word, ! regex_set); gtk_widget_set_sensitive(check_wordstart, ! regex_set); gtk_widget_set_sensitive(check_multiline, regex_set); } } static GeanyMatchInfo *match_info_new(GeanyFindFlags flags, gint start, gint end) { GeanyMatchInfo *info = g_slice_alloc(sizeof *info); info->flags = flags; info->start = start; info->end = end; info->match_text = NULL; return info; } void geany_match_info_free(GeanyMatchInfo *info) { g_free(info->match_text); g_slice_free1(sizeof *info, info); } /* find all in the given range. * Returns a list of allocated GeanyMatchInfo, should be freed using: * * foreach_slist(node, matches) * geany_match_info_free(node->data); * g_slist_free(matches); */ static GSList *find_range(ScintillaObject *sci, GeanyFindFlags flags, struct Sci_TextToFind *ttf) { GSList *matches = NULL; GeanyMatchInfo *info; g_return_val_if_fail(sci != NULL && ttf->lpstrText != NULL, NULL); if (! *ttf->lpstrText) return NULL; while (search_find_text(sci, flags, ttf, &info) != -1) { if (ttf->chrgText.cpMax > ttf->chrg.cpMax) { /* found text is partially out of range */ geany_match_info_free(info); break; } matches = g_slist_prepend(matches, info); ttf->chrg.cpMin = ttf->chrgText.cpMax; /* avoid rematching with empty matches like "(?=[a-z])" or "^$". * note we cannot assume a match will always be empty or not and then break out, since * matches like "a?(?=b)" will sometimes be empty and sometimes not */ if (ttf->chrgText.cpMax == ttf->chrgText.cpMin) ttf->chrg.cpMin ++; } return g_slist_reverse(matches); } /* Clears markers if text is null/empty. * @return Number of matches marked. */ gint search_mark_all(GeanyDocument *doc, const gchar *search_text, GeanyFindFlags flags) { gint count = 0; struct Sci_TextToFind ttf; GSList *match, *matches; g_return_val_if_fail(DOC_VALID(doc), 0); /* clear previous search indicators */ editor_indicator_clear(doc->editor, GEANY_INDICATOR_SEARCH); if (G_UNLIKELY(EMPTY(search_text))) return 0; ttf.chrg.cpMin = 0; ttf.chrg.cpMax = sci_get_length(doc->editor->sci); ttf.lpstrText = (gchar *)search_text; matches = find_range(doc->editor->sci, flags, &ttf); foreach_slist (match, matches) { GeanyMatchInfo *info = match->data; if (info->end != info->start) editor_indicator_set_on_range(doc->editor, GEANY_INDICATOR_SEARCH, info->start, info->end); count++; geany_match_info_free(info); } g_slist_free(matches); return count; } static void on_find_entry_activate(GtkEntry *entry, gpointer user_data) { on_find_dialog_response(NULL, GEANY_RESPONSE_FIND, user_data); } static void on_find_entry_activate_backward(GtkEntry *entry, gpointer user_data) { /* can't search backwards with a regexp */ if (search_data.flags & GEANY_FIND_REGEXP) utils_beep(); else on_find_dialog_response(NULL, GEANY_RESPONSE_FIND_PREVIOUS, user_data); } static GeanyFindFlags int_search_flags(gint match_case, gint whole_word, gint regexp, gint multiline, gint word_start) { return (match_case ? GEANY_FIND_MATCHCASE : 0) | (regexp ? GEANY_FIND_REGEXP : 0) | (whole_word ? GEANY_FIND_WHOLEWORD : 0) | (multiline ? GEANY_FIND_MULTILINE : 0) | /* SCFIND_WORDSTART overrides SCFIND_WHOLEWORD, but we want the opposite */ (word_start && !whole_word ? GEANY_FIND_WORDSTART : 0); } static void on_find_dialog_response(GtkDialog *dialog, gint response, gpointer user_data) { gtk_window_get_position(GTK_WINDOW(find_dlg.dialog), &find_dlg.position[0], &find_dlg.position[1]); stash_group_update(find_prefs, find_dlg.dialog); if (response == GTK_RESPONSE_CANCEL || response == GTK_RESPONSE_DELETE_EVENT) gtk_widget_hide(find_dlg.dialog); else { GeanyDocument *doc = document_get_current(); gboolean check_close = settings.find_close_dialog; if (doc == NULL) return; search_data.backwards = FALSE; search_data.search_bar = FALSE; g_free(search_data.text); g_free(search_data.original_text); search_data.text = g_strdup(gtk_entry_get_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN(user_data))))); search_data.original_text = g_strdup(search_data.text); search_data.flags = int_search_flags(settings.find_case_sensitive, settings.find_match_whole_word, settings.find_regexp, settings.find_regexp_multiline, settings.find_match_word_start); if (EMPTY(search_data.text)) { fail: utils_beep(); gtk_widget_grab_focus(find_dlg.entry); return; } if (search_data.flags & GEANY_FIND_REGEXP) { GRegex *regex = compile_regex(search_data.text, search_data.flags); if (!regex) goto fail; else g_regex_unref(regex); } else if (settings.find_escape_sequences) { if (! utils_str_replace_escape(search_data.text, FALSE)) goto fail; } ui_combo_box_add_to_history(GTK_COMBO_BOX_TEXT(user_data), search_data.original_text, 0); switch (response) { case GEANY_RESPONSE_FIND: case GEANY_RESPONSE_FIND_PREVIOUS: { gint result = document_find_text(doc, search_data.text, search_data.original_text, search_data.flags, (response == GEANY_RESPONSE_FIND_PREVIOUS), NULL, TRUE, GTK_WIDGET(find_dlg.dialog)); ui_set_search_entry_background(find_dlg.entry, (result > -1)); check_close = search_prefs.hide_find_dialog; break; } case GEANY_RESPONSE_FIND_IN_FILE: search_find_usage(search_data.text, search_data.original_text, search_data.flags, FALSE); break; case GEANY_RESPONSE_FIND_IN_SESSION: search_find_usage(search_data.text, search_data.original_text, search_data.flags, TRUE); break; case GEANY_RESPONSE_MARK: { gint count = search_mark_all(doc, search_data.text, search_data.flags); if (count == 0) ui_set_statusbar(FALSE, _("No matches found for \"%s\"."), search_data.original_text); else ui_set_statusbar(FALSE, ngettext("Found %d match for \"%s\".", "Found %d matches for \"%s\".", count), count, search_data.original_text); } break; } if (check_close) gtk_widget_hide(find_dlg.dialog); } } static void on_replace_find_entry_activate(GtkEntry *entry, gpointer user_data) { on_replace_dialog_response(NULL, GEANY_RESPONSE_FIND, NULL); } static void on_replace_entry_activate(GtkEntry *entry, gpointer user_data) { on_replace_dialog_response(NULL, search_prefs.replace_and_find_by_default ? GEANY_RESPONSE_REPLACE_AND_FIND : GEANY_RESPONSE_REPLACE, NULL); } static void replace_in_session(GeanyDocument *doc, GeanyFindFlags search_flags_re, gboolean search_replace_escape_re, const gchar *find, const gchar *replace, const gchar *original_find, const gchar *original_replace) { guint n, page_count, rep_count = 0, file_count = 0; /* replace in all documents following notebook tab order */ page_count = gtk_notebook_get_n_pages(GTK_NOTEBOOK(main_widgets.notebook)); for (n = 0; n < page_count; n++) { GeanyDocument *tmp_doc = document_get_from_page(n); gint reps = 0; reps = document_replace_all(tmp_doc, find, replace, original_find, original_replace, search_flags_re); rep_count += reps; if (reps) file_count++; } if (file_count == 0) { utils_beep(); ui_set_statusbar(FALSE, _("No matches found for \"%s\"."), original_find); return; } /* if only one file was changed, don't override that document's status message * so we don't have to translate 4 messages for ngettext */ if (file_count > 1) ui_set_statusbar(FALSE, _("Replaced %u matches in %u documents."), rep_count, file_count); /* show which docs had replacements: */ gtk_notebook_set_current_page(GTK_NOTEBOOK(msgwindow.notebook), MSG_STATUS); ui_save_buttons_toggle(doc->changed); /* update save all */ } static void on_replace_dialog_response(GtkDialog *dialog, gint response, gpointer user_data) { GeanyDocument *doc = document_get_current(); GeanyFindFlags search_flags_re; gboolean search_backwards_re, search_replace_escape_re; gchar *find, *replace, *original_find = NULL, *original_replace = NULL; gtk_window_get_position(GTK_WINDOW(replace_dlg.dialog), &replace_dlg.position[0], &replace_dlg.position[1]); stash_group_update(replace_prefs, replace_dlg.dialog); if (response == GTK_RESPONSE_CANCEL || response == GTK_RESPONSE_DELETE_EVENT) { gtk_widget_hide(replace_dlg.dialog); return; } if (response == GEANY_RESPONSE_REPLACE_IN_SESSION) { if (! dialogs_show_question_full(replace_dlg.dialog, NULL, NULL, _("This operation will modify all open files which contain the text to replace."), _("Are you sure to replace in the whole session?"))) { return; } } search_backwards_re = settings.replace_search_backwards; search_replace_escape_re = settings.replace_escape_sequences; find = g_strdup(gtk_entry_get_text(GTK_ENTRY(replace_dlg.find_entry))); replace = g_strdup(gtk_entry_get_text(GTK_ENTRY(replace_dlg.replace_entry))); search_flags_re = int_search_flags(settings.replace_case_sensitive, settings.replace_match_whole_word, settings.replace_regexp, settings.replace_regexp_multiline, settings.replace_match_word_start); if ((response != GEANY_RESPONSE_FIND) && (search_flags_re & GEANY_FIND_MATCHCASE) && (strcmp(find, replace) == 0)) goto fail; original_find = g_strdup(find); original_replace = g_strdup(replace); if (search_flags_re & GEANY_FIND_REGEXP) { GRegex *regex = compile_regex(find, search_flags_re); if (regex) g_regex_unref(regex); /* find escapes will be handled by GRegex */ if (!regex || !utils_str_replace_escape(replace, TRUE)) goto fail; } else if (search_replace_escape_re) { if (! utils_str_replace_escape(find, FALSE) || ! utils_str_replace_escape(replace, FALSE)) goto fail; } ui_combo_box_add_to_history(GTK_COMBO_BOX_TEXT(replace_dlg.find_combobox), original_find, 0); ui_combo_box_add_to_history(GTK_COMBO_BOX_TEXT(replace_dlg.replace_combobox), original_replace, 0); switch (response) { case GEANY_RESPONSE_REPLACE_AND_FIND: { gint rep = document_replace_text(doc, find, original_find, replace, search_flags_re, search_backwards_re); if (rep != -1) document_find_text(doc, find, original_find, search_flags_re, search_backwards_re, NULL, TRUE, NULL); break; } case GEANY_RESPONSE_REPLACE: document_replace_text(doc, find, original_find, replace, search_flags_re, search_backwards_re); break; case GEANY_RESPONSE_FIND: { gint result = document_find_text(doc, find, original_find, search_flags_re, search_backwards_re, NULL, TRUE, GTK_WIDGET(dialog)); ui_set_search_entry_background(replace_dlg.find_entry, (result > -1)); break; } case GEANY_RESPONSE_REPLACE_IN_FILE: if (! document_replace_all(doc, find, replace, original_find, original_replace, search_flags_re)) utils_beep(); break; case GEANY_RESPONSE_REPLACE_IN_SESSION: replace_in_session(doc, search_flags_re, search_replace_escape_re, find, replace, original_find, original_replace); break; case GEANY_RESPONSE_REPLACE_IN_SEL: document_replace_sel(doc, find, replace, original_find, original_replace, search_flags_re); break; } switch (response) { case GEANY_RESPONSE_REPLACE_IN_SEL: case GEANY_RESPONSE_REPLACE_IN_FILE: case GEANY_RESPONSE_REPLACE_IN_SESSION: if (settings.replace_close_dialog) gtk_widget_hide(replace_dlg.dialog); } g_free(find); g_free(replace); g_free(original_find); g_free(original_replace); return; fail: utils_beep(); gtk_widget_grab_focus(replace_dlg.find_entry); g_free(find); g_free(replace); g_free(original_find); g_free(original_replace); } static GString *get_grep_options(void) { GString *gstr = g_string_new("-nHI"); /* line numbers, filenames, ignore binaries */ if (settings.fif_invert_results) g_string_append_c(gstr, 'v'); if (! settings.fif_case_sensitive) g_string_append_c(gstr, 'i'); if (settings.fif_match_whole_word) g_string_append_c(gstr, 'w'); if (settings.fif_recursive) g_string_append_c(gstr, 'r'); if (!settings.fif_regexp) g_string_append_c(gstr, 'F'); else g_string_append_c(gstr, 'E'); if (settings.fif_use_extra_options) { g_strstrip(settings.fif_extra_options); if (*settings.fif_extra_options != 0) { g_string_append_c(gstr, ' '); g_string_append(gstr, settings.fif_extra_options); } } g_strstrip(settings.fif_files); if (settings.fif_files_mode != FILES_MODE_ALL && *settings.fif_files) { GString *tmp; /* put --include= before each pattern */ tmp = g_string_new(settings.fif_files); do {} while (utils_string_replace_all(tmp, " ", " ")); g_string_prepend_c(tmp, ' '); utils_string_replace_all(tmp, " ", " --include="); g_string_append(gstr, tmp->str); g_string_free(tmp, TRUE); } return gstr; } static void on_find_in_files_dialog_response(GtkDialog *dialog, gint response, G_GNUC_UNUSED gpointer user_data) { gtk_window_get_position(GTK_WINDOW(fif_dlg.dialog), &fif_dlg.position[0], &fif_dlg.position[1]); stash_group_update(fif_prefs, fif_dlg.dialog); if (response == GTK_RESPONSE_ACCEPT) { GtkWidget *search_combo = fif_dlg.search_combo; const gchar *search_text = gtk_entry_get_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN(search_combo)))); GtkWidget *dir_combo = fif_dlg.dir_combo; const gchar *utf8_dir = gtk_entry_get_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN(dir_combo)))); GeanyEncodingIndex enc_idx = ui_encodings_combo_box_get_active_encoding(GTK_COMBO_BOX(fif_dlg.encoding_combo)); if (G_UNLIKELY(EMPTY(utf8_dir))) ui_set_statusbar(FALSE, _("Invalid directory for find in files.")); else if (!EMPTY(search_text)) { GString *opts = get_grep_options(); const gchar *enc = (enc_idx == GEANY_ENCODING_UTF_8) ? NULL : encodings_get_charset_from_index(enc_idx); if (search_find_in_files(search_text, utf8_dir, opts->str, enc)) { ui_combo_box_add_to_history(GTK_COMBO_BOX_TEXT(search_combo), search_text, 0); ui_combo_box_add_to_history(GTK_COMBO_BOX_TEXT(fif_dlg.files_combo), NULL, 0); ui_combo_box_add_to_history(GTK_COMBO_BOX_TEXT(dir_combo), utf8_dir, 0); gtk_widget_hide(fif_dlg.dialog); } g_string_free(opts, TRUE); } else ui_set_statusbar(FALSE, _("No text to find.")); } else gtk_widget_hide(fif_dlg.dialog); } static gboolean search_find_in_files(const gchar *utf8_search_text, const gchar *utf8_dir, const gchar *opts, const gchar *enc) { gchar **argv_prefix, **argv; gchar *command_grep; gchar *command_line, *dir; gchar *search_text = NULL; GError *error = NULL; gboolean ret = FALSE; gssize utf8_text_len; if (EMPTY(utf8_search_text) || ! utf8_dir) return TRUE; command_grep = g_find_program_in_path(tool_prefs.grep_cmd); if (command_grep == NULL) command_line = g_strdup_printf("%s %s --", tool_prefs.grep_cmd, opts); else { command_line = g_strdup_printf("\"%s\" %s --", command_grep, opts); g_free(command_grep); } /* convert the search text in the preferred encoding (if the text is not valid UTF-8. assume * it is already in the preferred encoding) */ utf8_text_len = strlen(utf8_search_text); if (enc != NULL && g_utf8_validate(utf8_search_text, utf8_text_len, NULL)) { search_text = g_convert(utf8_search_text, utf8_text_len, enc, "UTF-8", NULL, NULL, NULL); } if (search_text == NULL) search_text = g_strdup(utf8_search_text); argv_prefix = g_new(gchar*, 3); argv_prefix[0] = search_text; dir = utils_get_locale_from_utf8(utf8_dir); /* finally add the arguments(files to be searched) */ if (settings.fif_recursive) /* recursive option set */ { /* Use '.' so we get relative paths in the output */ argv_prefix[1] = g_strdup("."); argv_prefix[2] = NULL; argv = argv_prefix; } else { argv_prefix[1] = NULL; argv = search_get_argv((const gchar**)argv_prefix, dir); g_strfreev(argv_prefix); if (argv == NULL) /* no files */ { g_free(command_line); return FALSE; } } gtk_list_store_clear(msgwindow.store_msg); gtk_notebook_set_current_page(GTK_NOTEBOOK(msgwindow.notebook), MSG_MESSAGE); /* we can pass 'enc' without strdup'ing it here because it's a global const string and * always exits longer than the lifetime of this function */ if (spawn_with_callbacks(dir, command_line, argv, NULL, 0, NULL, NULL, search_read_io, (gpointer) enc, 0, search_read_io_stderr, (gpointer) enc, 0, search_finished, NULL, NULL, &error)) { gchar *utf8_str; ui_progress_bar_start(_("Searching...")); msgwin_set_messages_dir(dir); utf8_str = g_strdup_printf(_("%s %s -- %s (in directory: %s)"), tool_prefs.grep_cmd, opts, utf8_search_text, utf8_dir); msgwin_msg_add_string(COLOR_BLUE, -1, NULL, utf8_str); g_free(utf8_str); ret = TRUE; } else { ui_set_statusbar(TRUE, _("Cannot execute grep tool \"%s\": %s. " "Check the path setting in Preferences."), tool_prefs.grep_cmd, error->message); g_error_free(error); } utils_free_pointers(2, dir, command_line, NULL); g_strfreev(argv); return ret; } static gboolean pattern_list_match(GSList *patterns, const gchar *str) { GSList *item; foreach_slist(item, patterns) { if (g_pattern_match_string(item->data, str)) return TRUE; } return FALSE; } /* Creates an argument vector of strings, copying argv_prefix[] values for * the first arguments, then followed by filenames found in dir. * Returns NULL if no files were found, otherwise returned vector should be fully freed. */ static gchar **search_get_argv(const gchar **argv_prefix, const gchar *dir) { guint prefix_len, list_len, i, j; gchar **argv; GSList *list, *item, *patterns = NULL; GError *error = NULL; g_return_val_if_fail(dir != NULL, NULL); prefix_len = g_strv_length((gchar**)argv_prefix); list = utils_get_file_list(dir, &list_len, &error); if (error) { ui_set_statusbar(TRUE, _("Could not open directory (%s)"), error->message); g_error_free(error); return NULL; } if (list == NULL) return NULL; argv = g_new(gchar*, prefix_len + list_len + 1); for (i = 0, j = 0; i < prefix_len; i++) { if (g_str_has_prefix(argv_prefix[i], "--include=")) { const gchar *pat = &(argv_prefix[i][10]); /* the pattern part of the argument */ patterns = g_slist_prepend(patterns, g_pattern_spec_new(pat)); } else argv[j++] = g_strdup(argv_prefix[i]); } if (patterns) { GSList *pat; foreach_slist(item, list) { if (pattern_list_match(patterns, item->data)) argv[j++] = item->data; else g_free(item->data); } foreach_slist(pat, patterns) g_pattern_spec_free(pat->data); g_slist_free(patterns); } else { foreach_slist(item, list) argv[j++] = item->data; } argv[j] = NULL; g_slist_free(list); return argv; } static void read_fif_io(gchar *msg, GIOCondition condition, gchar *enc, gint msg_color) { if (condition & (G_IO_IN | G_IO_PRI)) { gchar *utf8_msg = NULL; g_strstrip(msg); /* enc is NULL when encoding is set to UTF-8, so we can skip any conversion */ if (enc != NULL) { if (! g_utf8_validate(msg, -1, NULL)) { utf8_msg = g_convert(msg, -1, "UTF-8", enc, NULL, NULL, NULL); } if (utf8_msg == NULL) utf8_msg = msg; } else utf8_msg = msg; msgwin_msg_add_string(msg_color, -1, NULL, utf8_msg); if (utf8_msg != msg) g_free(utf8_msg); } } static void search_read_io(GString *string, GIOCondition condition, gpointer data) { read_fif_io(string->str, condition, data, COLOR_BLACK); } static void search_read_io_stderr(GString *string, GIOCondition condition, gpointer data) { read_fif_io(string->str, condition, data, COLOR_DARK_RED); } static void search_finished(GPid child_pid, gint status, gpointer user_data) { const gchar *msg = _("Search failed."); gint exit_status; if (SPAWN_WIFEXITED(status)) { exit_status = SPAWN_WEXITSTATUS(status); } else if (SPAWN_WIFSIGNALED(status)) { exit_status = -1; g_warning("Find in Files: The command failed unexpectedly (signal received)."); } else { exit_status = 1; } switch (exit_status) { case 0: { gint count = gtk_tree_model_iter_n_children( GTK_TREE_MODEL(msgwindow.store_msg), NULL) - 1; gchar *text = ngettext( "Search completed with %d match.", "Search completed with %d matches.", count); msgwin_msg_add(COLOR_BLUE, -1, NULL, text, count); ui_set_statusbar(FALSE, text, count); break; } case 1: msg = _("No matches found."); /* fall through */ default: msgwin_msg_add_string(COLOR_BLUE, -1, NULL, msg); ui_set_statusbar(FALSE, "%s", msg); break; } utils_beep(); ui_progress_bar_stop(); } static GRegex *compile_regex(const gchar *str, GeanyFindFlags sflags) { GRegex *regex; GError *error = NULL; gint rflags = 0; if (sflags & GEANY_FIND_MULTILINE) rflags |= G_REGEX_MULTILINE; if (~sflags & GEANY_FIND_MATCHCASE) rflags |= G_REGEX_CASELESS; if (sflags & (GEANY_FIND_WHOLEWORD | GEANY_FIND_WORDSTART)) { geany_debug("%s: Unsupported regex flags found!", G_STRFUNC); } regex = g_regex_new(str, rflags, 0, &error); if (!regex) { ui_set_statusbar(FALSE, _("Bad regex: %s"), error->message); g_error_free(error); } return regex; } /* groups that don't exist are handled OK as len = end - start = (-1) - (-1) = 0 */ static gchar *get_regex_match_string(const gchar *text, const GeanyMatchInfo *match, guint nth) { const gint start = match->matches[nth].start; const gint end = match->matches[nth].end; return g_strndup(&text[start], end - start); } static gint find_regex(ScintillaObject *sci, guint pos, GRegex *regex, gboolean multiline, GeanyMatchInfo *match) { const gchar *text; GMatchInfo *minfo; guint document_length; gint ret = -1; gint offset = 0; document_length = (guint)sci_get_length(sci); if (document_length <= 0) return -1; /* skip empty documents */ g_return_val_if_fail(pos <= document_length, -1); if (multiline) { /* Warning: any SCI calls will invalidate 'text' after calling SCI_GETCHARACTERPOINTER */ text = (void*)SSM(sci, SCI_GETCHARACTERPOINTER, 0, 0); g_regex_match_full(regex, text, -1, pos, 0, &minfo, NULL); } else /* single-line mode, manually match against each line */ { gint line = sci_get_line_from_position(sci, pos); for (;;) { gint start = sci_get_position_from_line(sci, line); gint end = sci_get_line_end_position(sci, line); text = (void*)SSM(sci, SCI_GETRANGEPOINTER, start, end - start); if (g_regex_match_full(regex, text, end - start, pos - start, 0, &minfo, NULL)) { offset = start; break; } else /* not found, try next line */ { line ++; if (line >= sci_get_line_count(sci)) break; pos = sci_get_position_from_line(sci, line); /* don't free last info, it's freed below */ g_match_info_free(minfo); } } } /* Warning: minfo will become invalid when 'text' does! */ if (g_match_info_matches(minfo)) { guint i; /* copy whole match text and offsets before they become invalid */ SETPTR(match->match_text, g_match_info_fetch(minfo, 0)); foreach_range(i, G_N_ELEMENTS(match->matches)) { gint start = -1, end = -1; g_match_info_fetch_pos(minfo, (gint)i, &start, &end); match->matches[i].start = offset + start; match->matches[i].end = offset + end; } match->start = match->matches[0].start; match->end = match->matches[0].end; ret = match->start; } g_match_info_free(minfo); return ret; } static gint geany_find_flags_to_sci_flags(GeanyFindFlags flags) { g_warn_if_fail(! (flags & GEANY_FIND_REGEXP) || ! (flags & GEANY_FIND_MULTILINE)); return ((flags & GEANY_FIND_MATCHCASE) ? SCFIND_MATCHCASE : 0) | ((flags & GEANY_FIND_WHOLEWORD) ? SCFIND_WHOLEWORD : 0) | ((flags & GEANY_FIND_REGEXP) ? SCFIND_REGEXP | SCFIND_POSIX : 0) | ((flags & GEANY_FIND_WORDSTART) ? SCFIND_WORDSTART : 0); } gint search_find_prev(ScintillaObject *sci, const gchar *str, GeanyFindFlags flags, GeanyMatchInfo **match_) { gint ret; g_return_val_if_fail(! (flags & GEANY_FIND_REGEXP), -1); ret = sci_search_prev(sci, geany_find_flags_to_sci_flags(flags), str); if (ret != -1 && match_) *match_ = match_info_new(flags, ret, ret + strlen(str)); return ret; } gint search_find_next(ScintillaObject *sci, const gchar *str, GeanyFindFlags flags, GeanyMatchInfo **match_) { GeanyMatchInfo *match; GRegex *regex; gint ret = -1; gint pos; if (~flags & GEANY_FIND_REGEXP) { ret = sci_search_next(sci, geany_find_flags_to_sci_flags(flags), str); if (ret != -1 && match_) *match_ = match_info_new(flags, ret, ret + strlen(str)); return ret; } regex = compile_regex(str, flags); if (!regex) return -1; match = match_info_new(flags, 0, 0); pos = sci_get_current_position(sci); ret = find_regex(sci, pos, regex, flags & GEANY_FIND_MULTILINE, match); /* avoid re-matching the same position in case of empty matches */ if (ret == pos && match->matches[0].start == match->matches[0].end) ret = find_regex(sci, pos + 1, regex, flags & GEANY_FIND_MULTILINE, match); if (ret >= 0) sci_set_selection(sci, match->start, match->end); if (ret != -1 && match_) *match_ = match; else geany_match_info_free(match); g_regex_unref(regex); return ret; } gint search_replace_match(ScintillaObject *sci, const GeanyMatchInfo *match, const gchar *replace_text) { GString *str; gint ret = 0; gint i = 0; sci_set_target_start(sci, match->start); sci_set_target_end(sci, match->end); if (! (match->flags & GEANY_FIND_REGEXP)) return sci_replace_target(sci, replace_text, FALSE); str = g_string_new(replace_text); while (str->str[i]) { gchar *ptr = &str->str[i]; gchar *grp; gchar c; if (ptr[0] != '\\') { i++; continue; } c = ptr[1]; /* backslash or unnecessary escape */ if (c == '\\' || !isdigit(c)) { g_string_erase(str, i, 1); i++; continue; } /* digit escape */ g_string_erase(str, i, 2); /* fix match offsets by subtracting index of whole match start from the string */ grp = get_regex_match_string(match->match_text - match->matches[0].start, match, c - '0'); g_string_insert(str, i, grp); i += strlen(grp); g_free(grp); } ret = sci_replace_target(sci, str->str, FALSE); g_string_free(str, TRUE); return ret; } gint search_find_text(ScintillaObject *sci, GeanyFindFlags flags, struct Sci_TextToFind *ttf, GeanyMatchInfo **match_) { GeanyMatchInfo *match = NULL; GRegex *regex; gint ret; if (~flags & GEANY_FIND_REGEXP) { ret = sci_find_text(sci, geany_find_flags_to_sci_flags(flags), ttf); if (ret != -1 && match_) *match_ = match_info_new(flags, ttf->chrgText.cpMin, ttf->chrgText.cpMax); return ret; } regex = compile_regex(ttf->lpstrText, flags); if (!regex) return -1; match = match_info_new(flags, 0, 0); ret = find_regex(sci, ttf->chrg.cpMin, regex, flags & GEANY_FIND_MULTILINE, match); if (ret >= ttf->chrg.cpMax) ret = -1; else if (ret >= 0) { ttf->chrgText.cpMin = match->start; ttf->chrgText.cpMax = match->end; } if (ret != -1 && match_) *match_ = match; else geany_match_info_free(match); g_regex_unref(regex); return ret; } static gint find_document_usage(GeanyDocument *doc, const gchar *search_text, GeanyFindFlags flags) { gchar *buffer, *short_file_name; struct Sci_TextToFind ttf; gint count = 0; gint prev_line = -1; GSList *match, *matches; g_return_val_if_fail(DOC_VALID(doc), 0); short_file_name = g_path_get_basename(DOC_FILENAME(doc)); ttf.chrg.cpMin = 0; ttf.chrg.cpMax = sci_get_length(doc->editor->sci); ttf.lpstrText = (gchar *)search_text; matches = find_range(doc->editor->sci, flags, &ttf); foreach_slist (match, matches) { GeanyMatchInfo *info = match->data; gint line = sci_get_line_from_position(doc->editor->sci, info->start); if (line != prev_line) { buffer = sci_get_line(doc->editor->sci, line); msgwin_msg_add(COLOR_BLACK, line + 1, doc, "%s:%d: %s", short_file_name, line + 1, g_strstrip(buffer)); g_free(buffer); prev_line = line; } count++; geany_match_info_free(info); } g_slist_free(matches); g_free(short_file_name); return count; } void search_find_usage(const gchar *search_text, const gchar *original_search_text, GeanyFindFlags flags, gboolean in_session) { GeanyDocument *doc; gint count = 0; doc = document_get_current(); g_return_if_fail(doc != NULL); if (G_UNLIKELY(EMPTY(search_text))) { utils_beep(); return; } gtk_notebook_set_current_page(GTK_NOTEBOOK(msgwindow.notebook), MSG_MESSAGE); gtk_list_store_clear(msgwindow.store_msg); if (! in_session) { /* use current document */ count = find_document_usage(doc, search_text, flags); } else { guint i; for (i = 0; i < documents_array->len; i++) { if (documents[i]->is_valid) { count += find_document_usage(documents[i], search_text, flags); } } } if (count == 0) /* no matches were found */ { ui_set_statusbar(FALSE, _("No matches found for \"%s\"."), original_search_text); msgwin_msg_add(COLOR_BLUE, -1, NULL, _("No matches found for \"%s\"."), original_search_text); } else { ui_set_statusbar(FALSE, ngettext( "Found %d match for \"%s\".", "Found %d matches for \"%s\".", count), count, original_search_text); msgwin_msg_add(COLOR_BLUE, -1, NULL, ngettext( "Found %d match for \"%s\".", "Found %d matches for \"%s\".", count), count, original_search_text); } } /* ttf is updated to include the last match position (ttf->chrg.cpMin) and * the new search range end (ttf->chrg.cpMax). * Note: Normally you would call sci_start/end_undo_action() around this call. */ guint search_replace_range(ScintillaObject *sci, struct Sci_TextToFind *ttf, GeanyFindFlags flags, const gchar *replace_text) { gint count = 0; gint offset = 0; /* difference between search pos and replace pos */ GSList *match, *matches; g_return_val_if_fail(sci != NULL && ttf->lpstrText != NULL && replace_text != NULL, 0); if (! *ttf->lpstrText) return 0; matches = find_range(sci, flags, ttf); foreach_slist (match, matches) { GeanyMatchInfo *info = match->data; gint replace_len; info->start += offset; info->end += offset; replace_len = search_replace_match(sci, info, replace_text); offset += replace_len - (info->end - info->start); count ++; /* on last match, update the last match/new range end */ if (! match->next) { ttf->chrg.cpMin = info->start; ttf->chrg.cpMax += offset; } geany_match_info_free(info); } g_slist_free(matches); return count; } void search_find_again(gboolean change_direction) { GeanyDocument *doc = document_get_current(); g_return_if_fail(doc != NULL); if (search_data.text) { gboolean forward = ! search_data.backwards; gint result = document_find_text(doc, search_data.text, search_data.original_text, search_data.flags, change_direction ? forward : !forward, NULL, FALSE, NULL); if (result > -1) editor_display_current_line(doc->editor, 0.3F); if (search_data.search_bar) ui_set_search_entry_background( toolbar_get_widget_child_by_name("SearchEntry"), (result > -1)); } } geany-2.0/src/highlighting.c0000644000175000017500000015466314514252267013026 00000000000000/* * highlighting.c - this file is part of Geany, a fast and lightweight IDE * * Copyright 2005 The Geany contributors * * This program 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; either version 2 of the License, or * (at your option) any later version. * * This program 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /** * @file highlighting.h * Syntax highlighting for the different filetypes, using the Scintilla lexers. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include "highlighting.h" #include "highlightingmappings.h" #include "app.h" #include "dialogs.h" #include "document.h" #include "editor.h" #include "filetypesprivate.h" #include "sciwrappers.h" #include "support.h" #include "symbols.h" #include "ui_utils.h" #include "utils.h" #include "SciLexer.h" #include #include #include #include #include #define GEANY_COLORSCHEMES_SUBDIR "colorschemes" /* Whitespace has to be set after setting wordchars. */ #define GEANY_WHITESPACE_CHARS " \t" "!\"#$%&'()*+,-./:;<=>?@[\\]^`{|}~" static gchar *whitespace_chars = NULL; typedef struct { gsize count; /* number of styles */ GeanyLexerStyle *styling; /* array of styles, NULL if not used or uninitialised */ gchar **keywords; gchar *wordchars; /* NULL used for style sets with no styles */ gchar **property_keys; gchar **property_values; } StyleSet; /* each filetype has a styleset but GEANY_FILETYPES_NONE uses common_style_set for styling */ static StyleSet *style_sets = NULL; enum /* Geany common styling */ { GCS_DEFAULT, GCS_SELECTION, GCS_BRACE_GOOD, GCS_BRACE_BAD, GCS_MARGIN_LINENUMBER, GCS_MARGIN_FOLDING, GCS_FOLD_SYMBOL_HIGHLIGHT, GCS_CURRENT_LINE, GCS_CARET, GCS_INDENT_GUIDE, GCS_WHITE_SPACE, GCS_LINE_WRAP_VISUALS, GCS_LINE_WRAP_INDENT, GCS_TRANSLUCENCY, GCS_MARKER_LINE, GCS_MARKER_SEARCH, GCS_MARKER_MARK, GCS_MARKER_TRANSLUCENCY, GCS_LINE_HEIGHT, GCS_CALLTIPS, GCS_INDICATOR_ERROR, GCS_MAX }; static struct { GeanyLexerStyle styling[GCS_MAX]; /* icon style, 1-4 */ gint fold_marker; /* vertical line style, 0-2 */ gint fold_lines; /* horizontal line when folded, 0-2 */ gint fold_draw_line; gchar *wordchars; } common_style_set = { { { 0 } }, 0, 0, 0, NULL }; /* For filetypes.common [named_styles] section. * 0xBBGGRR format. * e.g. "comment" => &GeanyLexerStyle{0x0000d0, 0xffffff, FALSE, FALSE} */ static GHashTable *named_style_hash = NULL; /* 0xBBGGRR format, set by "default" named style. */ static GeanyLexerStyle gsd_default = {0x000000, 0xffffff, FALSE, FALSE}; /* filetypes should use the filetypes.foo [lexer_properties] group instead of hardcoding */ static void sci_set_property(ScintillaObject *sci, const gchar *name, const gchar *value) { SSM(sci, SCI_SETPROPERTY, (uptr_t) name, (sptr_t) value); } static void new_styleset(guint file_type_id, gsize styling_count) { StyleSet *set = &style_sets[file_type_id]; set->count = styling_count; set->styling = g_new0(GeanyLexerStyle, styling_count); } static void free_styleset(guint file_type_id) { StyleSet *style_ptr; style_ptr = &style_sets[file_type_id]; style_ptr->count = 0; g_free(style_ptr->styling); style_ptr->styling = NULL; g_strfreev(style_ptr->keywords); style_ptr->keywords = NULL; g_free(style_ptr->wordchars); style_ptr->wordchars = NULL; g_strfreev(style_ptr->property_keys); style_ptr->property_keys = NULL; g_strfreev(style_ptr->property_values); style_ptr->property_values = NULL; } static void get_keyfile_keywords(GKeyFile *config, GKeyFile *configh, const gchar *key, guint ft_id, guint pos) { style_sets[ft_id].keywords[pos] = utils_get_setting(string, configh, config, "keywords", key, ""); } static void get_keyfile_wordchars(GKeyFile *config, GKeyFile *configh, gchar **wordchars, const gchar *default_wordchars) { *wordchars = utils_get_setting(string, configh, config, "settings", "wordchars", default_wordchars); } static gboolean read_named_style(const gchar *named_style, GeanyLexerStyle *style) { GeanyLexerStyle *cs; gchar *comma, *name = NULL; const gchar *bold = NULL; const gchar *italic = NULL; g_return_val_if_fail(named_style, FALSE); name = utils_strdupa(named_style); /* named_style must not be written to, may be a static string */ comma = strstr(name, ","); if (comma) { bold = strstr(comma, ",bold"); italic = strstr(comma, ",italic"); *comma = '\0'; /* terminate name to make lookup work */ } cs = g_hash_table_lookup(named_style_hash, name); if (cs) { *style = *cs; if (bold) style->bold = !style->bold; if (italic) style->italic = !style->italic; } else { *style = gsd_default; } return (cs != NULL); } /* Parses a color in `str` which can be an HTML color (ex. #0099cc), * an abbreviated HTML color (ex. #09c) or a hex string color * (ex. 0x0099cc). The result of the conversion is stored into the * location pointed to by `clr`. */ static void parse_color(GKeyFile *kf, const gchar *str, gint *clr) { gint c; gchar *named_color = NULL; g_return_if_fail(clr != NULL); if (G_UNLIKELY(EMPTY(str))) return; named_color = g_key_file_get_string(kf, "named_colors", str, NULL); if (named_color) str = named_color; c = utils_parse_color_to_bgr(str); if (c == -1) geany_debug("Bad color '%s'", str); else *clr = c; g_free(named_color); } static void parse_keyfile_style(GKeyFile *kf, gchar **list, const GeanyLexerStyle *default_style, GeanyLexerStyle *style) { gsize len; g_return_if_fail(default_style); g_return_if_fail(style); *style = *default_style; if (!list) return; len = g_strv_length(list); if (len == 0) return; else if (len == 1) { gchar **items = g_strsplit(list[0], ",", 0); if (items != NULL) { if (g_strv_length(items) > 0) { if (g_hash_table_lookup(named_style_hash, items[0]) != NULL) { if (!read_named_style(list[0], style)) geany_debug("Unable to read named style '%s'", items[0]); g_strfreev(items); return; } else if (strchr(list[0], ',') != NULL) { geany_debug("Unknown named style '%s'", items[0]); g_strfreev(items); return; } } g_strfreev(items); } } switch (len) { case 4: style->italic = utils_atob(list[3]); /* fall through */ case 3: style->bold = utils_atob(list[2]); /* fall through */ case 2: parse_color(kf, list[1], &style->background); /* fall through */ case 1: parse_color(kf, list[0], &style->foreground); } } static void get_keyfile_style(GKeyFile *config, GKeyFile *configh, const gchar *key_name, GeanyLexerStyle *style) { gchar **list; gsize len; g_return_if_fail(config); g_return_if_fail(configh); g_return_if_fail(key_name); g_return_if_fail(style); list = g_key_file_get_string_list(configh, "styling", key_name, &len, NULL); if (list == NULL) { list = g_key_file_get_string_list(config, "styling", key_name, &len, NULL); parse_keyfile_style(config, list, &gsd_default, style); } else parse_keyfile_style(configh, list, &gsd_default, style); g_strfreev(list); } static void convert_int(const gchar *int_str, gint *val) { gchar *end; gint v = strtol(int_str, &end, 10); if (int_str != end) *val = v; } /* Get first and second integer numbers, store in foreground and background fields of @a style. */ static void get_keyfile_int(GKeyFile *config, GKeyFile *configh, const gchar *section, const gchar *key, gint fdefault_val, gint sdefault_val, GeanyLexerStyle *style) { gchar **list; gsize len; GeanyLexerStyle def = {fdefault_val, sdefault_val, FALSE, FALSE}; g_return_if_fail(config); g_return_if_fail(configh); g_return_if_fail(section); g_return_if_fail(key); list = g_key_file_get_string_list(configh, section, key, &len, NULL); if (list == NULL) list = g_key_file_get_string_list(config, section, key, &len, NULL); *style = def; if (!list) return; if (list[0]) { convert_int(list[0], &style->foreground); if (list[1]) { convert_int(list[1], &style->background); } } g_strfreev(list); } /* first or second can be NULL. */ static void get_keyfile_ints(GKeyFile *config, GKeyFile *configh, const gchar *section, const gchar *key, gint fdefault_val, gint sdefault_val, gint *first, gint *second) { GeanyLexerStyle tmp_style; get_keyfile_int(config, configh, section, key, fdefault_val, sdefault_val, &tmp_style); if (first) *first = tmp_style.foreground; if (second) *second = tmp_style.background; } static guint invert(guint icolour) { if (interface_prefs.highlighting_invert_all) return 0xffffff - icolour; return icolour; } static GeanyLexerStyle *get_style(guint ft_id, guint styling_index) { g_assert(ft_id < filetypes_array->len); if (G_UNLIKELY(ft_id == GEANY_FILETYPES_NONE)) { g_assert(styling_index < GCS_MAX); return &common_style_set.styling[styling_index]; } else { StyleSet *set = &style_sets[ft_id]; g_assert(styling_index < set->count); return &set->styling[styling_index]; } } static void set_sci_style(ScintillaObject *sci, guint style, guint ft_id, guint styling_index) { GeanyLexerStyle *style_ptr = get_style(ft_id, styling_index); SSM(sci, SCI_STYLESETFORE, style, invert(style_ptr->foreground)); SSM(sci, SCI_STYLESETBACK, style, invert(style_ptr->background)); SSM(sci, SCI_STYLESETBOLD, style, style_ptr->bold); SSM(sci, SCI_STYLESETITALIC, style, style_ptr->italic); } void highlighting_free_styles(void) { guint i; for (i = 0; i < filetypes_array->len; i++) free_styleset(i); if (named_style_hash) g_hash_table_destroy(named_style_hash); g_free(style_sets); } static gchar* get_keyfile_whitespace_chars(GKeyFile *config, GKeyFile *configh) { return utils_get_setting(string, configh, config, "settings", "whitespace_chars", GEANY_WHITESPACE_CHARS); } static void add_named_style(GKeyFile *config, const gchar *key) { const gchar group[] = "named_styles"; gchar **list; gsize len; list = g_key_file_get_string_list(config, group, key, &len, NULL); /* we allow a named style to reference another style above it */ if (list && len >= 1) { GeanyLexerStyle *style = g_new0(GeanyLexerStyle, 1); parse_keyfile_style(config, list, &gsd_default, style); g_hash_table_insert(named_style_hash, g_strdup(key), style); } g_strfreev(list); } static void get_named_styles(GKeyFile *config) { const gchar group[] = "named_styles"; gchar **keys = g_key_file_get_keys(config, group, NULL, NULL); gchar **ptr = keys; if (!ptr) return; while (1) { const gchar *key = *ptr; if (!key) break; /* don't replace already read default style with system one */ if (!g_str_equal(key, "default")) add_named_style(config, key); ptr++; } g_strfreev(keys); } static GKeyFile *utils_key_file_new(const gchar *filename) { GKeyFile *config = g_key_file_new(); g_key_file_load_from_file(config, filename, G_KEY_FILE_KEEP_COMMENTS, NULL); return config; } static void load_named_styles(GKeyFile *config, GKeyFile *config_home) { const gchar *scheme = editor_prefs.color_scheme; gboolean free_kf = FALSE; if (named_style_hash) g_hash_table_destroy(named_style_hash); /* reloading */ named_style_hash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); if (!EMPTY(scheme)) { gchar *path, *path_home; path = g_build_path(G_DIR_SEPARATOR_S, app->datadir, GEANY_COLORSCHEMES_SUBDIR, scheme, NULL); path_home = g_build_path(G_DIR_SEPARATOR_S, app->configdir, GEANY_COLORSCHEMES_SUBDIR, scheme, NULL); if (g_file_test(path, G_FILE_TEST_EXISTS) || g_file_test(path_home, G_FILE_TEST_EXISTS)) { config = utils_key_file_new(path); config_home = utils_key_file_new(path_home); free_kf = TRUE; } /* if color scheme is missing, use default */ g_free(path); g_free(path_home); } /* first set default to the "default" named style */ add_named_style(config, "default"); read_named_style("default", &gsd_default); /* in case user overrides but not with both colors */ add_named_style(config_home, "default"); read_named_style("default", &gsd_default); get_named_styles(config); /* home overrides any system named style */ get_named_styles(config_home); if (free_kf) { g_key_file_free(config); g_key_file_free(config_home); } } static void styleset_common_init(GKeyFile *config, GKeyFile *config_home) { load_named_styles(config, config_home); get_keyfile_style(config, config_home, "default", &common_style_set.styling[GCS_DEFAULT]); get_keyfile_style(config, config_home, "selection", &common_style_set.styling[GCS_SELECTION]); get_keyfile_style(config, config_home, "brace_good", &common_style_set.styling[GCS_BRACE_GOOD]); get_keyfile_style(config, config_home, "brace_bad", &common_style_set.styling[GCS_BRACE_BAD]); get_keyfile_style(config, config_home, "margin_linenumber", &common_style_set.styling[GCS_MARGIN_LINENUMBER]); get_keyfile_style(config, config_home, "margin_folding", &common_style_set.styling[GCS_MARGIN_FOLDING]); get_keyfile_style(config, config_home, "fold_symbol_highlight", &common_style_set.styling[GCS_FOLD_SYMBOL_HIGHLIGHT]); get_keyfile_style(config, config_home, "current_line", &common_style_set.styling[GCS_CURRENT_LINE]); get_keyfile_style(config, config_home, "caret", &common_style_set.styling[GCS_CARET]); get_keyfile_style(config, config_home, "indent_guide", &common_style_set.styling[GCS_INDENT_GUIDE]); get_keyfile_style(config, config_home, "white_space", &common_style_set.styling[GCS_WHITE_SPACE]); get_keyfile_style(config, config_home, "marker_line", &common_style_set.styling[GCS_MARKER_LINE]); get_keyfile_style(config, config_home, "marker_search", &common_style_set.styling[GCS_MARKER_SEARCH]); get_keyfile_style(config, config_home, "marker_mark", &common_style_set.styling[GCS_MARKER_MARK]); get_keyfile_style(config, config_home, "calltips", &common_style_set.styling[GCS_CALLTIPS]); get_keyfile_style(config, config_home, "indicator_error", &common_style_set.styling[GCS_INDICATOR_ERROR]); get_keyfile_ints(config, config_home, "styling", "folding_style", 1, 1, &common_style_set.fold_marker, &common_style_set.fold_lines); get_keyfile_ints(config, config_home, "styling", "folding_horiz_line", 2, 0, &common_style_set.fold_draw_line, NULL); get_keyfile_ints(config, config_home, "styling", "caret_width", 1, 0, &common_style_set.styling[GCS_CARET].background, NULL); /* caret.foreground used earlier */ get_keyfile_int(config, config_home, "styling", "line_wrap_visuals", 3, 0, &common_style_set.styling[GCS_LINE_WRAP_VISUALS]); get_keyfile_int(config, config_home, "styling", "line_wrap_indent", 0, 0, &common_style_set.styling[GCS_LINE_WRAP_INDENT]); get_keyfile_int(config, config_home, "styling", "translucency", 256, 256, &common_style_set.styling[GCS_TRANSLUCENCY]); get_keyfile_int(config, config_home, "styling", "marker_translucency", 256, 256, &common_style_set.styling[GCS_MARKER_TRANSLUCENCY]); get_keyfile_int(config, config_home, "styling", "line_height", 0, 0, &common_style_set.styling[GCS_LINE_HEIGHT]); g_free(common_style_set.wordchars); get_keyfile_wordchars(config, config_home, &common_style_set.wordchars, GEANY_WORDCHARS); g_free(whitespace_chars); whitespace_chars = get_keyfile_whitespace_chars(config, config_home); } static void set_character_classes(ScintillaObject *sci, guint ft_id) { const gchar *word = (ft_id == GEANY_FILETYPES_NONE ? common_style_set.wordchars : style_sets[ft_id].wordchars); gchar *whitespace; guint i, j; SSM(sci, SCI_SETWORDCHARS, 0, (sptr_t) word); /* setting wordchars resets character classes, so we have to set whitespaces after * wordchars, but we want wordchars to have precenence over whitepace chars */ whitespace = g_malloc0(strlen(whitespace_chars) + 1); for (i = 0, j = 0; whitespace_chars[i] != 0; i++) { if (! strchr(word, whitespace_chars[i])) whitespace[j++] = whitespace_chars[i]; } whitespace[j] = 0; SSM(sci, SCI_SETWHITESPACECHARS, 0, (sptr_t) whitespace); g_free(whitespace); } static void styleset_common(ScintillaObject *sci, guint ft_id) { GeanyLexerStyle *style; SSM(sci, SCI_STYLECLEARALL, 0, 0); set_character_classes(sci, ft_id); /* caret colour, style and width */ SSM(sci, SCI_SETCARETFORE, invert(common_style_set.styling[GCS_CARET].foreground), 0); SSM(sci, SCI_SETCARETWIDTH, common_style_set.styling[GCS_CARET].background, 0); if (common_style_set.styling[GCS_CARET].bold) SSM(sci, SCI_SETCARETSTYLE, CARETSTYLE_BLOCK, 0); else SSM(sci, SCI_SETCARETSTYLE, CARETSTYLE_LINE, 0); /* line height */ SSM(sci, SCI_SETEXTRAASCENT, common_style_set.styling[GCS_LINE_HEIGHT].foreground, 0); SSM(sci, SCI_SETEXTRADESCENT, common_style_set.styling[GCS_LINE_HEIGHT].background, 0); /* colourise the current line */ SSM(sci, SCI_SETCARETLINEBACK, invert(common_style_set.styling[GCS_CURRENT_LINE].background), 0); /* bold=enable current line */ SSM(sci, SCI_SETCARETLINEVISIBLE, common_style_set.styling[GCS_CURRENT_LINE].bold, 0); /* Translucency for current line and selection */ SSM(sci, SCI_SETCARETLINEBACKALPHA, common_style_set.styling[GCS_TRANSLUCENCY].foreground, 0); SSM(sci, SCI_SETSELALPHA, common_style_set.styling[GCS_TRANSLUCENCY].background, 0); /* line wrapping visuals */ SSM(sci, SCI_SETWRAPVISUALFLAGS, common_style_set.styling[GCS_LINE_WRAP_VISUALS].foreground, 0); SSM(sci, SCI_SETWRAPVISUALFLAGSLOCATION, common_style_set.styling[GCS_LINE_WRAP_VISUALS].background, 0); SSM(sci, SCI_SETWRAPSTARTINDENT, common_style_set.styling[GCS_LINE_WRAP_INDENT].foreground, 0); SSM(sci, SCI_SETWRAPINDENTMODE, common_style_set.styling[GCS_LINE_WRAP_INDENT].background, 0); /* Error indicator */ SSM(sci, SCI_INDICSETSTYLE, GEANY_INDICATOR_ERROR, INDIC_SQUIGGLEPIXMAP); SSM(sci, SCI_INDICSETFORE, GEANY_INDICATOR_ERROR, invert(common_style_set.styling[GCS_INDICATOR_ERROR].foreground)); /* Search indicator, used for 'Mark' matches */ SSM(sci, SCI_INDICSETSTYLE, GEANY_INDICATOR_SEARCH, INDIC_ROUNDBOX); SSM(sci, SCI_INDICSETFORE, GEANY_INDICATOR_SEARCH, invert(common_style_set.styling[GCS_MARKER_SEARCH].background)); SSM(sci, SCI_INDICSETALPHA, GEANY_INDICATOR_SEARCH, 60); /* Snippet cursor indicator, when inserting snippets with multiple * cursor positions. */ SSM(sci, SCI_INDICSETSTYLE, GEANY_INDICATOR_SNIPPET, INDIC_DOTBOX); SSM(sci, SCI_INDICSETALPHA, GEANY_INDICATOR_SNIPPET, 60); /* define marker symbols * 0 -> line marker */ SSM(sci, SCI_MARKERDEFINE, 0, SC_MARK_SHORTARROW); SSM(sci, SCI_MARKERSETFORE, 0, invert(common_style_set.styling[GCS_MARKER_LINE].foreground)); SSM(sci, SCI_MARKERSETBACK, 0, invert(common_style_set.styling[GCS_MARKER_LINE].background)); SSM(sci, SCI_MARKERSETALPHA, 0, common_style_set.styling[GCS_MARKER_TRANSLUCENCY].foreground); /* 1 -> user marker */ SSM(sci, SCI_MARKERDEFINE, 1, SC_MARK_PLUS); SSM(sci, SCI_MARKERSETFORE, 1, invert(common_style_set.styling[GCS_MARKER_MARK].foreground)); SSM(sci, SCI_MARKERSETBACK, 1, invert(common_style_set.styling[GCS_MARKER_MARK].background)); SSM(sci, SCI_MARKERSETALPHA, 1, common_style_set.styling[GCS_MARKER_TRANSLUCENCY].background); /* 2 -> folding marker, other folding settings */ SSM(sci, SCI_SETMARGINTYPEN, 2, SC_MARGIN_SYMBOL); SSM(sci, SCI_SETMARGINMASKN, 2, SC_MASK_FOLDERS); /* drawing a horizontal line when text if folded */ switch (common_style_set.fold_draw_line) { case 1: { SSM(sci, SCI_SETFOLDFLAGS, 4, 0); break; } case 2: { SSM(sci, SCI_SETFOLDFLAGS, 16, 0); break; } default: { SSM(sci, SCI_SETFOLDFLAGS, 0, 0); break; } } /* choose the folding style - boxes or circles, I prefer boxes, so it is default ;-) */ SSM(sci, SCI_MARKERDEFINE, SC_MARKNUM_FOLDEREND, SC_MARK_EMPTY); SSM(sci, SCI_MARKERDEFINE, SC_MARKNUM_FOLDEROPENMID, SC_MARK_EMPTY); switch (common_style_set.fold_marker) { case 2: SSM(sci, SCI_MARKERDEFINE, SC_MARKNUM_FOLDEROPEN, SC_MARK_CIRCLEMINUS); SSM(sci, SCI_MARKERDEFINE, SC_MARKNUM_FOLDER, SC_MARK_CIRCLEPLUS); SSM(sci, SCI_MARKERDEFINE, SC_MARKNUM_FOLDEREND, SC_MARK_CIRCLEPLUSCONNECTED); SSM(sci, SCI_MARKERDEFINE, SC_MARKNUM_FOLDEROPENMID, SC_MARK_CIRCLEMINUSCONNECTED); break; default: SSM(sci, SCI_MARKERDEFINE, SC_MARKNUM_FOLDEROPEN, SC_MARK_BOXMINUS); SSM(sci, SCI_MARKERDEFINE, SC_MARKNUM_FOLDER, SC_MARK_BOXPLUS); SSM(sci, SCI_MARKERDEFINE, SC_MARKNUM_FOLDEREND, SC_MARK_BOXPLUSCONNECTED); SSM(sci, SCI_MARKERDEFINE, SC_MARKNUM_FOLDEROPENMID, SC_MARK_BOXMINUSCONNECTED); break; case 3: SSM(sci, SCI_MARKERDEFINE, SC_MARKNUM_FOLDEROPEN, SC_MARK_ARROWDOWN); SSM(sci, SCI_MARKERDEFINE, SC_MARKNUM_FOLDER, SC_MARK_ARROW); break; case 4: SSM(sci, SCI_MARKERDEFINE, SC_MARKNUM_FOLDEROPEN, SC_MARK_MINUS); SSM(sci, SCI_MARKERDEFINE, SC_MARKNUM_FOLDER, SC_MARK_PLUS); break; } /* choose the folding style - straight or curved, I prefer straight, so it is default ;-) */ switch (common_style_set.fold_lines) { case 2: SSM(sci, SCI_MARKERDEFINE, SC_MARKNUM_FOLDERMIDTAIL, SC_MARK_TCORNERCURVE); SSM(sci, SCI_MARKERDEFINE, SC_MARKNUM_FOLDERTAIL, SC_MARK_LCORNERCURVE); SSM(sci, SCI_MARKERDEFINE, SC_MARKNUM_FOLDERSUB, SC_MARK_VLINE); break; default: SSM(sci, SCI_MARKERDEFINE, SC_MARKNUM_FOLDERMIDTAIL, SC_MARK_TCORNER); SSM(sci, SCI_MARKERDEFINE, SC_MARKNUM_FOLDERTAIL, SC_MARK_LCORNER); SSM(sci, SCI_MARKERDEFINE, SC_MARKNUM_FOLDERSUB, SC_MARK_VLINE); break; case 0: SSM(sci, SCI_MARKERDEFINE, SC_MARKNUM_FOLDERMIDTAIL, SC_MARK_EMPTY); SSM(sci, SCI_MARKERDEFINE, SC_MARKNUM_FOLDERTAIL, SC_MARK_EMPTY); SSM(sci, SCI_MARKERDEFINE, SC_MARKNUM_FOLDERSUB, SC_MARK_EMPTY); break; } { gint markers[] = { SC_MARKNUM_FOLDEROPEN, SC_MARKNUM_FOLDER, SC_MARKNUM_FOLDERSUB, SC_MARKNUM_FOLDERTAIL, SC_MARKNUM_FOLDEREND, SC_MARKNUM_FOLDEROPENMID, SC_MARKNUM_FOLDERMIDTAIL }; guint i; foreach_range(i, G_N_ELEMENTS(markers)) { SSM(sci, SCI_MARKERSETFORE, markers[i], invert(common_style_set.styling[GCS_FOLD_SYMBOL_HIGHLIGHT].foreground)); SSM(sci, SCI_MARKERSETBACK, markers[i], invert(common_style_set.styling[GCS_MARGIN_FOLDING].foreground)); } } /* set some common defaults */ sci_set_property(sci, "fold", "1"); sci_set_property(sci, "fold.compact", "0"); sci_set_property(sci, "fold.comment", "1"); sci_set_property(sci, "fold.preprocessor", "1"); sci_set_property(sci, "fold.at.else", "1"); style = &common_style_set.styling[GCS_SELECTION]; if (!style->bold && !style->italic) { geany_debug("selection style is set to invisible - ignoring!"); style->italic = TRUE; style->background = 0xc0c0c0; } /* bold (3rd argument) is whether to override default foreground selection */ SSM(sci, SCI_SETSELFORE, style->bold, invert(style->foreground)); /* italic (4th argument) is whether to override default background selection */ SSM(sci, SCI_SETSELBACK, style->italic, invert(style->background)); SSM(sci, SCI_SETFOLDMARGINCOLOUR, 1, invert(common_style_set.styling[GCS_MARGIN_FOLDING].background)); SSM(sci, SCI_SETFOLDMARGINHICOLOUR, 1, invert(common_style_set.styling[GCS_MARGIN_FOLDING].background)); set_sci_style(sci, STYLE_LINENUMBER, GEANY_FILETYPES_NONE, GCS_MARGIN_LINENUMBER); set_sci_style(sci, STYLE_BRACELIGHT, GEANY_FILETYPES_NONE, GCS_BRACE_GOOD); set_sci_style(sci, STYLE_BRACEBAD, GEANY_FILETYPES_NONE, GCS_BRACE_BAD); set_sci_style(sci, STYLE_INDENTGUIDE, GEANY_FILETYPES_NONE, GCS_INDENT_GUIDE); /* bold = common whitespace settings enabled */ SSM(sci, SCI_SETWHITESPACEFORE, common_style_set.styling[GCS_WHITE_SPACE].bold, invert(common_style_set.styling[GCS_WHITE_SPACE].foreground)); SSM(sci, SCI_SETWHITESPACEBACK, common_style_set.styling[GCS_WHITE_SPACE].italic, invert(common_style_set.styling[GCS_WHITE_SPACE].background)); if (common_style_set.styling[GCS_CALLTIPS].bold) SSM(sci, SCI_CALLTIPSETFORE, invert(common_style_set.styling[GCS_CALLTIPS].foreground), 1); if (common_style_set.styling[GCS_CALLTIPS].italic) SSM(sci, SCI_CALLTIPSETBACK, invert(common_style_set.styling[GCS_CALLTIPS].background), 1); } /* Merge & assign global typedefs and user secondary keywords. * keyword_idx is used for both style_sets[].keywords and scintilla keyword style number */ static void merge_type_keywords(ScintillaObject *sci, guint ft_id, guint keyword_idx) { const gchar *user_words = style_sets[ft_id].keywords[keyword_idx]; GString *s; s = symbols_find_typenames_as_string(filetypes[ft_id]->lang, TRUE); if (G_UNLIKELY(s == NULL)) s = g_string_sized_new(200); else g_string_append_c(s, ' '); /* append a space as delimiter to the existing list of words */ g_string_append(s, user_words); sci_set_keywords(sci, keyword_idx, s->str); g_string_free(s, TRUE); } static void styleset_init_from_mapping(guint ft_id, GKeyFile *config, GKeyFile *config_home, const HLStyle *styles, gsize n_styles, const HLKeyword *keywords, gsize n_keywords) { gsize i; /* styles */ new_styleset(ft_id, n_styles); foreach_range(i, n_styles) { GeanyLexerStyle *style = &style_sets[ft_id].styling[i]; get_keyfile_style(config, config_home, styles[i].name, style); } /* keywords */ if (n_keywords < 1) style_sets[ft_id].keywords = NULL; else { style_sets[ft_id].keywords = g_new(gchar*, n_keywords + 1); foreach_range(i, n_keywords) get_keyfile_keywords(config, config_home, keywords[i].key, ft_id, i); style_sets[ft_id].keywords[i] = NULL; } } /* STYLE_DEFAULT will be set to match the first style. */ static void styleset_from_mapping(ScintillaObject *sci, guint ft_id, guint lexer, const HLStyle *styles, gsize n_styles, const HLKeyword *keywords, gsize n_keywords, const HLProperty *properties, gsize n_properties) { gsize i; g_assert(ft_id != GEANY_FILETYPES_NONE); /* lexer */ sci_set_lexer(sci, lexer); /* styles */ styleset_common(sci, ft_id); if (n_styles > 0) { /* first style is also default one */ set_sci_style(sci, STYLE_DEFAULT, ft_id, 0); foreach_range(i, n_styles) { if (styles[i].fill_eol) SSM(sci, SCI_STYLESETEOLFILLED, styles[i].style, TRUE); set_sci_style(sci, styles[i].style, ft_id, i); } } /* keywords */ foreach_range(i, n_keywords) { if (keywords[i].merge) merge_type_keywords(sci, ft_id, i); else sci_set_keywords(sci, keywords[i].id, style_sets[ft_id].keywords[i]); } /* properties */ foreach_range(i, n_properties) sci_set_property(sci, properties[i].property, properties[i].value); } static void styleset_default(ScintillaObject *sci, guint ft_id) { sci_set_lexer(sci, SCLEX_NULL); /* we need to set STYLE_DEFAULT before we call SCI_STYLECLEARALL in styleset_common() */ set_sci_style(sci, STYLE_DEFAULT, GEANY_FILETYPES_NONE, GCS_DEFAULT); styleset_common(sci, ft_id); } static void get_key_values(GKeyFile *config, const gchar *group, gchar **keys, gchar **values) { while (*keys) { gchar *str = g_key_file_get_string(config, group, *keys, NULL); if (str) SETPTR(*values, str); keys++; values++; } } static void read_properties(GeanyFiletype *ft, GKeyFile *config, GKeyFile *configh) { gchar group[] = "lexer_properties"; gchar **keys; gchar **keysh = g_key_file_get_keys(configh, group, NULL, NULL); gchar **ptr; /* remove overridden keys from system keyfile */ foreach_strv(ptr, keysh) g_key_file_remove_key(config, group, *ptr, NULL); /* merge sys and user keys */ keys = g_key_file_get_keys(config, group, NULL, NULL); keys = utils_strv_join(keys, keysh); if (keys) { gchar **values = g_new0(gchar*, g_strv_length(keys) + 1); style_sets[ft->id].property_keys = keys; style_sets[ft->id].property_values = values; get_key_values(config, group, keys, values); get_key_values(configh, group, keys, values); } } static guint get_lexer_filetype(GeanyFiletype *ft) { ft = FALLBACK(ft->lexer_filetype, ft); return ft->id; } #define init_styleset_case(LANG_NAME) \ case (GEANY_FILETYPES_##LANG_NAME): \ styleset_init_from_mapping(filetype_idx, config, configh, \ highlighting_styles_##LANG_NAME, \ HL_N_ENTRIES(highlighting_styles_##LANG_NAME), \ highlighting_keywords_##LANG_NAME, \ HL_N_ENTRIES(highlighting_keywords_##LANG_NAME)); \ break /* Called by filetypes_load_config(). */ void highlighting_init_styles(guint filetype_idx, GKeyFile *config, GKeyFile *configh) { GeanyFiletype *ft = filetypes[filetype_idx]; guint lexer_id = get_lexer_filetype(ft); gchar *default_str; if (!style_sets) style_sets = g_new0(StyleSet, filetypes_array->len); /* Clear old information if necessary - e.g. when reloading config */ free_styleset(filetype_idx); read_properties(ft, config, configh); /* If a default style exists, check it uses a named style * Note: almost all filetypes have a "default" style, except HTML ones */ default_str = utils_get_setting(string, configh, config, "styling", "default", "default"); ft->priv->warn_color_scheme = !g_ascii_isalpha(*default_str); g_free(default_str); /* None filetype handled specially */ if (filetype_idx == GEANY_FILETYPES_NONE) { styleset_common_init(config, configh); return; } /* All stylesets depend on filetypes.common */ filetypes_load_config(GEANY_FILETYPES_NONE, FALSE); switch (lexer_id) { init_styleset_case(ABAQUS); init_styleset_case(ADA); init_styleset_case(ASCIIDOC); init_styleset_case(ASM); init_styleset_case(AU3); init_styleset_case(BASIC); init_styleset_case(BATCH); init_styleset_case(C); init_styleset_case(CAML); init_styleset_case(CMAKE); init_styleset_case(COBOL); init_styleset_case(COFFEESCRIPT); init_styleset_case(CONF); init_styleset_case(CSS); init_styleset_case(D); init_styleset_case(DIFF); init_styleset_case(LISP); init_styleset_case(ERLANG); init_styleset_case(DOCBOOK); init_styleset_case(F77); init_styleset_case(FORTH); init_styleset_case(FORTRAN); init_styleset_case(GDSCRIPT); init_styleset_case(GO); init_styleset_case(HASKELL); init_styleset_case(HAXE); init_styleset_case(AS); init_styleset_case(HTML); init_styleset_case(JAVA); init_styleset_case(JS); init_styleset_case(JULIA); init_styleset_case(LATEX); init_styleset_case(LUA); init_styleset_case(MAKE); init_styleset_case(MATLAB); init_styleset_case(MARKDOWN); init_styleset_case(NSIS); init_styleset_case(OBJECTIVEC); init_styleset_case(PASCAL); init_styleset_case(PERL); init_styleset_case(PHP); init_styleset_case(PO); init_styleset_case(POWERSHELL); init_styleset_case(PYTHON); init_styleset_case(R); init_styleset_case(RUBY); init_styleset_case(RUST); init_styleset_case(SH); init_styleset_case(SMALLTALK); init_styleset_case(SQL); init_styleset_case(TCL); init_styleset_case(TXT2TAGS); init_styleset_case(VHDL); init_styleset_case(VERILOG); init_styleset_case(XML); init_styleset_case(YAML); init_styleset_case(ZEPHIR); default: if (ft->lexer_filetype) geany_debug("Filetype %s has a recursive lexer_filetype %s set!", ft->name, ft->lexer_filetype->name); } /* should be done in filetypes.c really: */ get_keyfile_wordchars(config, configh, &style_sets[filetype_idx].wordchars, common_style_set.wordchars); } #define styleset_case(LANG_NAME) \ case (GEANY_FILETYPES_##LANG_NAME): \ styleset_from_mapping(sci, ft->id, highlighting_lexer_##LANG_NAME, \ highlighting_styles_##LANG_NAME, \ HL_N_ENTRIES(highlighting_styles_##LANG_NAME), \ highlighting_keywords_##LANG_NAME, \ HL_N_ENTRIES(highlighting_keywords_##LANG_NAME), \ highlighting_properties_##LANG_NAME, \ HL_N_ENTRIES(highlighting_properties_##LANG_NAME)); \ break /** Sets up highlighting and other visual settings. * @param sci Scintilla widget. * @param ft Filetype settings to use. */ GEANY_API_SYMBOL void highlighting_set_styles(ScintillaObject *sci, GeanyFiletype *ft) { guint lexer_id = get_lexer_filetype(ft); filetypes_load_config(ft->id, FALSE); /* load filetypes.ext */ switch (lexer_id) { styleset_case(ABAQUS); styleset_case(ADA); styleset_case(ASCIIDOC); styleset_case(ASM); styleset_case(AU3); styleset_case(BASIC); styleset_case(BATCH); styleset_case(C); styleset_case(CAML); styleset_case(CMAKE); styleset_case(COBOL); styleset_case(COFFEESCRIPT); styleset_case(CONF); styleset_case(CSS); styleset_case(D); styleset_case(DIFF); styleset_case(LISP); styleset_case(ERLANG); styleset_case(DOCBOOK); styleset_case(F77); styleset_case(FORTH); styleset_case(FORTRAN); styleset_case(GDSCRIPT); styleset_case(GO); styleset_case(HASKELL); styleset_case(HAXE); styleset_case(AS); styleset_case(HTML); styleset_case(JAVA); styleset_case(JS); styleset_case(JULIA); styleset_case(LATEX); styleset_case(LUA); styleset_case(MAKE); styleset_case(MARKDOWN); styleset_case(MATLAB); styleset_case(NSIS); styleset_case(OBJECTIVEC); styleset_case(PASCAL); styleset_case(PERL); styleset_case(PHP); styleset_case(PO); styleset_case(POWERSHELL); styleset_case(PYTHON); styleset_case(R); styleset_case(RUBY); styleset_case(RUST); styleset_case(SH); styleset_case(SMALLTALK); styleset_case(SQL); styleset_case(TCL); styleset_case(TXT2TAGS); styleset_case(VHDL); styleset_case(VERILOG); styleset_case(XML); styleset_case(YAML); styleset_case(ZEPHIR); case GEANY_FILETYPES_NONE: default: styleset_default(sci, ft->id); } /* [lexer_properties] settings */ if (style_sets[ft->id].property_keys) { gchar **prop = style_sets[ft->id].property_keys; gchar **val = style_sets[ft->id].property_values; while (*prop) { sci_set_property(sci, *prop, *val); prop++; val++; } } } /** Retrieves a style @a style_id for the filetype @a ft_id. * If the style was not already initialised * (e.g. by by opening a file of this type), it will be initialised. The returned pointer is * owned by Geany and must not be freed. * @param ft_id Filetype ID, e.g. @c GEANY_FILETYPES_DIFF. * @param style_id A Scintilla lexer style, e.g. @c SCE_DIFF_ADDED. See scintilla/lexilla/include/SciLexer.h. * @return A pointer to the style struct. * @see Scintilla messages @c SCI_STYLEGETFORE, etc, for use with scintilla_send_message(). */ GEANY_API_SYMBOL const GeanyLexerStyle *highlighting_get_style(gint ft_id, gint style_id) { g_return_val_if_fail(ft_id >= 0 && (guint) ft_id < filetypes_array->len, NULL); g_return_val_if_fail(style_id >= 0, NULL); /* ensure filetype loaded */ filetypes_load_config((guint) ft_id, FALSE); /* TODO: style_id might not be the real array index (Scintilla styles are not always synced * with array indices) */ return get_style((guint) ft_id, (guint) style_id); } enum { SCHEME_MARKUP, SCHEME_FILE, SCHEME_COLUMNS }; static void on_color_scheme_changed(GtkTreeSelection *treesel, gpointer dummy) { GtkTreeModel *model; GtkTreeIter iter; gchar *fname; gchar *path; if (!gtk_tree_selection_get_selected(treesel, &model, &iter)) return; gtk_tree_model_get(model, &iter, SCHEME_FILE, &fname, -1); /* check if default item */ if (!fname) { SETPTR(editor_prefs.color_scheme, NULL); filetypes_reload(); return; } SETPTR(fname, utils_get_locale_from_utf8(fname)); /* fname is just the basename from the menu item, so prepend the custom files path */ path = g_build_path(G_DIR_SEPARATOR_S, app->configdir, GEANY_COLORSCHEMES_SUBDIR, fname, NULL); if (!g_file_test(path, G_FILE_TEST_EXISTS)) { /* try the system path */ g_free(path); path = g_build_path(G_DIR_SEPARATOR_S, app->datadir, GEANY_COLORSCHEMES_SUBDIR, fname, NULL); } if (g_file_test(path, G_FILE_TEST_EXISTS)) { SETPTR(editor_prefs.color_scheme, fname); fname = NULL; filetypes_reload(); } else { SETPTR(fname, utils_get_utf8_from_locale(fname)); ui_set_statusbar(TRUE, _("Could not find file '%s'."), fname); } g_free(path); g_free(fname); } static gchar *utils_get_setting_locale_string(GKeyFile *keyfile, const gchar *group, const gchar *key, const gchar *default_value) { gchar *result = g_key_file_get_locale_string(keyfile, group, key, NULL, NULL); return FALLBACK(result, g_strdup(default_value)); } static void add_color_scheme_item(GtkListStore *store, gchar *name, gchar *desc, const gchar *fn, GtkTreeIter *current_iter) { GtkTreeIter iter; gchar *markup; /* reuse parameters */ name = g_markup_escape_text(name, -1); desc = g_markup_escape_text(desc, -1); markup = g_strdup_printf("%s\n%s", name, desc); g_free(name); g_free(desc); gtk_list_store_append(store, &iter); gtk_list_store_set(store, &iter, SCHEME_MARKUP, markup, SCHEME_FILE, fn, -1); g_free(markup); /* select the current iter if the the color scheme matches, or if it's the * default (fn == NULL), in case of bad config file. the default theme is * first anyway so if a later scheme matches it will override default */ if ((! fn || utils_str_equal(fn, editor_prefs.color_scheme)) && current_iter) *current_iter = iter; } static void add_color_scheme_file(GtkListStore *store, const gchar *fname, GtkTreeIter *current_iter) { GKeyFile *hkeyfile, *skeyfile; gchar *path, *theme_name, *theme_desc; gchar *theme_fn = utils_get_utf8_from_locale(fname); path = g_build_filename(app->configdir, GEANY_COLORSCHEMES_SUBDIR, fname, NULL); hkeyfile = utils_key_file_new(path); SETPTR(path, g_build_filename(app->datadir, GEANY_COLORSCHEMES_SUBDIR, fname, NULL)); skeyfile = utils_key_file_new(path); theme_name = utils_get_setting(locale_string, hkeyfile, skeyfile, "theme_info", "name", theme_fn); theme_desc = utils_get_setting(locale_string, hkeyfile, skeyfile, "theme_info", "description", NULL); add_color_scheme_item(store, theme_name, theme_desc, theme_fn, current_iter); g_free(path); g_free(theme_fn); g_free(theme_name); g_free(theme_desc); g_key_file_free(hkeyfile); g_key_file_free(skeyfile); } static gboolean add_color_scheme_items(GtkListStore *store, GtkTreeIter *current_iter) { GSList *list, *node; add_color_scheme_item(store, _("Default"), _("Default"), NULL, current_iter); list = utils_get_config_files(GEANY_COLORSCHEMES_SUBDIR); foreach_slist(node, list) { gchar *fname = node->data; if (g_str_has_suffix(fname, ".conf")) add_color_scheme_file(store, fname, current_iter); g_free(fname); } g_slist_free(list); return list != NULL; } static void on_color_scheme_dialog_response(GtkWidget *dialog, gint response, gpointer *dialog_ptr) { *dialog_ptr = NULL; gtk_widget_destroy(dialog); } void highlighting_show_color_scheme_dialog(void) { static GtkWidget *dialog = NULL; GtkListStore *store = gtk_list_store_new(SCHEME_COLUMNS, G_TYPE_STRING, G_TYPE_STRING); GtkCellRenderer *text_renderer; GtkTreeViewColumn *column; GtkTreeSelection *treesel; GtkTreeIter current_iter; GtkTreePath *path; GtkWidget *vbox, *swin, *tree; GeanyDocument *doc; doc = document_get_current(); if (doc && doc->file_type->priv->warn_color_scheme) dialogs_show_msgbox_with_secondary(GTK_MESSAGE_WARNING, _("The current filetype overrides the default style."), _("This may cause color schemes to display incorrectly.")); tree = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store)); g_object_unref(store); gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(tree), TRUE); gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(tree), FALSE); text_renderer = gtk_cell_renderer_text_new(); g_object_set(text_renderer, "wrap-mode", PANGO_WRAP_WORD, NULL); column = gtk_tree_view_column_new_with_attributes( NULL, text_renderer, "markup", SCHEME_MARKUP, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(tree), column); add_color_scheme_items(store, ¤t_iter); treesel = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree)); gtk_tree_selection_select_iter(treesel, ¤t_iter); path = gtk_tree_model_get_path(GTK_TREE_MODEL(store), ¤t_iter); gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(tree), path, NULL, FALSE, 0, 0); gtk_tree_path_free(path); g_signal_connect(treesel, "changed", G_CALLBACK(on_color_scheme_changed), NULL); /* old dialog may still be showing */ if (dialog) gtk_widget_destroy(dialog); dialog = gtk_dialog_new_with_buttons(_("Color Schemes"), GTK_WINDOW(main_widgets.window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, NULL); vbox = ui_dialog_vbox_new(GTK_DIALOG(dialog)); gtk_box_set_spacing(GTK_BOX(vbox), 6); gtk_widget_set_name(dialog, "GeanyDialog"); gtk_window_set_default_size(GTK_WINDOW(dialog), GEANY_DEFAULT_DIALOG_HEIGHT * 7/4, GEANY_DEFAULT_DIALOG_HEIGHT); swin = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(swin), GTK_SHADOW_IN); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(swin), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_container_add(GTK_CONTAINER(swin), tree); gtk_box_pack_start(GTK_BOX(vbox), swin, TRUE, TRUE, 0); g_signal_connect(dialog, "response", G_CALLBACK(on_color_scheme_dialog_response), &dialog); gtk_widget_show_all(dialog); } /** Checks whether the given style is a string for the given lexer. * * @param lexer Scintilla lexer type (@c SCLEX_*). * @param style Scintilla style (@c SCE_*). * * @return @c TRUE if the style is a string, @c FALSE otherwise. */ GEANY_API_SYMBOL gboolean highlighting_is_string_style(gint lexer, gint style) { /* Don't forget STRINGEOL, to prevent completion whilst typing a string with no closing char. */ switch (lexer) { case SCLEX_CPP: return (style == SCE_C_CHARACTER || style == SCE_C_STRING || style == SCE_C_STRINGEOL || style == SCE_C_STRINGRAW || style == SCE_C_VERBATIM || style == SCE_C_USERLITERAL || style == SCE_C_TRIPLEVERBATIM || style == SCE_C_REGEX || style == SCE_C_HASHQUOTEDSTRING || style == SCE_C_ESCAPESEQUENCE); case SCLEX_PASCAL: return (style == SCE_PAS_CHARACTER || style == SCE_PAS_STRING || style == SCE_PAS_STRINGEOL); case SCLEX_D: return (style == SCE_D_STRING || style == SCE_D_STRINGEOL || style == SCE_D_CHARACTER || style == SCE_D_STRINGB || style == SCE_D_STRINGR); case SCLEX_PYTHON: return (style == SCE_P_STRING || style == SCE_P_TRIPLE || style == SCE_P_TRIPLEDOUBLE || style == SCE_P_CHARACTER || style == SCE_P_FSTRING || style == SCE_P_FCHARACTER || style == SCE_P_FTRIPLE || style == SCE_P_FTRIPLEDOUBLE || style == SCE_P_STRINGEOL); case SCLEX_GDSCRIPT: return (style == SCE_GD_STRING || style == SCE_GD_TRIPLE || style == SCE_GD_TRIPLEDOUBLE || style == SCE_GD_CHARACTER || style == SCE_GD_STRINGEOL); case SCLEX_F77: case SCLEX_FORTRAN: return (style == SCE_F_STRING1 || style == SCE_F_STRING2 || style == SCE_F_STRINGEOL); case SCLEX_PERL: return (style == SCE_PL_STRING || style == SCE_PL_CHARACTER || style == SCE_PL_HERE_DELIM || style == SCE_PL_HERE_Q || style == SCE_PL_HERE_QQ || style == SCE_PL_HERE_QX || style == SCE_PL_POD || style == SCE_PL_STRING_Q || style == SCE_PL_STRING_QQ || style == SCE_PL_STRING_QX || style == SCE_PL_STRING_QR || style == SCE_PL_STRING_QW || style == SCE_PL_POD_VERB || style == SCE_PL_REGEX || style == SCE_PL_REGEX_VAR || style == SCE_PL_XLAT /* we don't include any STRING_*_VAR for autocompletion */); case SCLEX_PO: return (style == SCE_PO_MSGCTXT_TEXT || style == SCE_PO_MSGCTXT_TEXT_EOL || style == SCE_PO_MSGID_TEXT || style == SCE_PO_MSGID_TEXT_EOL || style == SCE_PO_MSGSTR_TEXT || style == SCE_PO_MSGSTR_TEXT_EOL); case SCLEX_R: return (style == SCE_R_STRING); case SCLEX_RUBY: return (style == SCE_RB_CHARACTER || style == SCE_RB_STRING || style == SCE_RB_HERE_DELIM || style == SCE_RB_HERE_Q || style == SCE_RB_HERE_QQ || style == SCE_RB_HERE_QX || style == SCE_RB_REGEX || style == SCE_RB_STRING_Q || style == SCE_RB_STRING_QQ || style == SCE_RB_STRING_QX || style == SCE_RB_STRING_QR || style == SCE_RB_STRING_QW || style == SCE_RB_POD); case SCLEX_BASH: return (style == SCE_SH_STRING); case SCLEX_SQL: return (style == SCE_SQL_STRING); case SCLEX_TCL: return (style == SCE_TCL_IN_QUOTE); case SCLEX_LUA: return (style == SCE_LUA_LITERALSTRING || style == SCE_LUA_CHARACTER || style == SCE_LUA_STRINGEOL || style == SCE_LUA_STRING); case SCLEX_HASKELL: case SCLEX_LITERATEHASKELL: return (style == SCE_HA_CHARACTER || style == SCE_HA_STRINGEOL || style == SCE_HA_STRING); case SCLEX_FREEBASIC: return (style == SCE_B_STRING || style == SCE_B_STRINGEOL); case SCLEX_OCTAVE: return (style == SCE_MATLAB_STRING || style == SCE_MATLAB_DOUBLEQUOTESTRING); case SCLEX_JULIA: return (style == SCE_JULIA_CHAR || style == SCE_JULIA_STRING || style == SCE_JULIA_DOCSTRING || style == SCE_JULIA_COMMAND || style == SCE_JULIA_STRINGINTERP); case SCLEX_XML: case SCLEX_HTML: case SCLEX_PHPSCRIPT: return ( style == SCE_HBA_STRING || style == SCE_HBA_STRINGEOL || style == SCE_HB_STRING || style == SCE_HB_STRINGEOL || style == SCE_H_CDATA || style == SCE_H_DOUBLESTRING || style == SCE_HJA_DOUBLESTRING || style == SCE_HJA_SINGLESTRING || style == SCE_HJA_STRINGEOL || style == SCE_HJA_REGEX || style == SCE_HJ_DOUBLESTRING || style == SCE_HJ_SINGLESTRING || style == SCE_HJ_STRINGEOL || style == SCE_HJ_REGEX || style == SCE_HPA_CHARACTER || style == SCE_HPA_STRING || style == SCE_HPA_TRIPLE || style == SCE_HPA_TRIPLEDOUBLE || style == SCE_HP_CHARACTER || style == SCE_HPHP_HSTRING || /* HSTRING is a heredoc */ style == SCE_HPHP_HSTRING_VARIABLE || style == SCE_HPHP_SIMPLESTRING || style == SCE_HP_STRING || style == SCE_HP_TRIPLE || style == SCE_HP_TRIPLEDOUBLE || style == SCE_H_SGML_DOUBLESTRING || style == SCE_H_SGML_SIMPLESTRING || style == SCE_H_SINGLESTRING); case SCLEX_CMAKE: return (style == SCE_CMAKE_STRINGDQ || style == SCE_CMAKE_STRINGLQ || style == SCE_CMAKE_STRINGRQ || style == SCE_CMAKE_STRINGVAR); case SCLEX_NSIS: return (style == SCE_NSIS_STRINGDQ || style == SCE_NSIS_STRINGLQ || style == SCE_NSIS_STRINGRQ || style == SCE_NSIS_STRINGVAR); case SCLEX_ADA: return (style == SCE_ADA_CHARACTER || style == SCE_ADA_STRING || style == SCE_ADA_CHARACTEREOL || style == SCE_ADA_STRINGEOL); case SCLEX_ABAQUS: return (style == SCE_ABAQUS_STRING); case SCLEX_RUST: return (style == SCE_RUST_CHARACTER || style == SCE_RUST_BYTECHARACTER || style == SCE_RUST_STRING || style == SCE_RUST_STRINGR || style == SCE_RUST_BYTESTRING || style == SCE_RUST_BYTESTRINGR || style == SCE_RUST_LEXERROR); case SCLEX_COFFEESCRIPT: return (style == SCE_COFFEESCRIPT_CHARACTER || style == SCE_COFFEESCRIPT_STRING || style == SCE_COFFEESCRIPT_REGEX || style == SCE_COFFEESCRIPT_VERBOSE_REGEX || style == SCE_COFFEESCRIPT_STRINGEOL); case SCLEX_VERILOG: return (style == SCE_V_STRING); case SCLEX_VHDL: return (style == SCE_VHDL_STRING || style == SCE_VHDL_STRINGEOL); case SCLEX_CAML: return (style == SCE_CAML_CHAR || style == SCE_CAML_STRING); case SCLEX_CSS: return (style == SCE_CSS_DOUBLESTRING || style == SCE_CSS_SINGLESTRING); case SCLEX_ERLANG: return (style == SCE_ERLANG_STRING || style == SCE_ERLANG_CHARACTER); case SCLEX_LISP: return (style == SCE_LISP_STRING || style == SCE_LISP_STRINGEOL); case SCLEX_FORTH: return (style == SCE_FORTH_STRING); case SCLEX_POWERSHELL: return (style == SCE_POWERSHELL_STRING || style == SCE_POWERSHELL_CHARACTER); case SCLEX_BATCH: case SCLEX_DIFF: case SCLEX_LATEX: case SCLEX_MAKEFILE: case SCLEX_MARKDOWN: case SCLEX_PROPERTIES: case SCLEX_TXT2TAGS: case SCLEX_YAML: /* there is no string type in those lexers, listing here just for completeness */ return FALSE; case SCLEX_AU3: return (style == SCE_AU3_STRING); } return FALSE; } /** Checks whether the given style is a comment for the given lexer. * * @param lexer Scintilla lexer type (@c SCLEX_*). * @param style Scintilla style (@c SCE_*). * * @return @c TRUE if the style is a comment, @c FALSE otherwise. */ GEANY_API_SYMBOL gboolean highlighting_is_comment_style(gint lexer, gint style) { switch (lexer) { case SCLEX_COBOL: case SCLEX_CPP: return (style == SCE_C_COMMENT || style == SCE_C_COMMENTLINE || style == SCE_C_COMMENTDOC || style == SCE_C_PREPROCESSORCOMMENT || style == SCE_C_PREPROCESSORCOMMENTDOC || style == SCE_C_COMMENTLINEDOC || style == SCE_C_COMMENTDOCKEYWORD || style == SCE_C_COMMENTDOCKEYWORDERROR || style == SCE_C_TASKMARKER); case SCLEX_PASCAL: return (style == SCE_PAS_COMMENT || style == SCE_PAS_COMMENT2 || style == SCE_PAS_COMMENTLINE); case SCLEX_D: return (style == SCE_D_COMMENT || style == SCE_D_COMMENTLINE || style == SCE_D_COMMENTDOC || style == SCE_D_COMMENTNESTED || style == SCE_D_COMMENTLINEDOC || style == SCE_D_COMMENTDOCKEYWORD || style == SCE_D_COMMENTDOCKEYWORDERROR); case SCLEX_PYTHON: return (style == SCE_P_COMMENTLINE || style == SCE_P_COMMENTBLOCK); case SCLEX_F77: case SCLEX_FORTRAN: return (style == SCE_F_COMMENT); case SCLEX_PERL: return (style == SCE_PL_COMMENTLINE); case SCLEX_PROPERTIES: return (style == SCE_PROPS_COMMENT); case SCLEX_PO: return (style == SCE_PO_COMMENT || style == SCE_PO_PROGRAMMER_COMMENT); case SCLEX_LATEX: return (style == SCE_L_COMMENT || style == SCE_L_COMMENT2); case SCLEX_MAKEFILE: return (style == SCE_MAKE_COMMENT); case SCLEX_RUBY: return (style == SCE_RB_COMMENTLINE); case SCLEX_BASH: return (style == SCE_SH_COMMENTLINE); case SCLEX_R: return (style == SCE_R_COMMENT); case SCLEX_SQL: return (style == SCE_SQL_COMMENT || style == SCE_SQL_COMMENTLINE || style == SCE_SQL_COMMENTDOC || style == SCE_SQL_COMMENTLINEDOC || style == SCE_SQL_COMMENTDOCKEYWORD || style == SCE_SQL_COMMENTDOCKEYWORDERROR); case SCLEX_TCL: return (style == SCE_TCL_COMMENT || style == SCE_TCL_COMMENTLINE || style == SCE_TCL_COMMENT_BOX || style == SCE_TCL_BLOCK_COMMENT); case SCLEX_OCTAVE: return (style == SCE_MATLAB_COMMENT); case SCLEX_JULIA: return (style == SCE_JULIA_COMMENT); case SCLEX_LUA: return (style == SCE_LUA_COMMENT || style == SCE_LUA_COMMENTLINE || style == SCE_LUA_COMMENTDOC); case SCLEX_HASKELL: case SCLEX_LITERATEHASKELL: return (style == SCE_HA_COMMENTLINE || style == SCE_HA_COMMENTBLOCK || style == SCE_HA_COMMENTBLOCK2 || style == SCE_HA_COMMENTBLOCK3 || style == SCE_HA_LITERATE_COMMENT || style == SCE_HA_LITERATE_CODEDELIM); case SCLEX_FREEBASIC: return (style == SCE_B_COMMENT || style == SCE_B_COMMENTBLOCK || style == SCE_B_DOCLINE || style == SCE_B_DOCBLOCK || style == SCE_B_DOCKEYWORD); case SCLEX_YAML: return (style == SCE_YAML_COMMENT); case SCLEX_XML: case SCLEX_HTML: case SCLEX_PHPSCRIPT: return ( style == SCE_HBA_COMMENTLINE || style == SCE_HB_COMMENTLINE || style == SCE_H_COMMENT || style == SCE_HJA_COMMENT || style == SCE_HJA_COMMENTDOC || style == SCE_HJA_COMMENTLINE || style == SCE_HJ_COMMENT || style == SCE_HJ_COMMENTDOC || style == SCE_HJ_COMMENTLINE || style == SCE_HPA_COMMENTLINE || style == SCE_HP_COMMENTLINE || style == SCE_HPHP_COMMENT || style == SCE_HPHP_COMMENTLINE || style == SCE_H_SGML_COMMENT); case SCLEX_CMAKE: return (style == SCE_CMAKE_COMMENT); case SCLEX_NSIS: return (style == SCE_NSIS_COMMENT || style == SCE_NSIS_COMMENTBOX); case SCLEX_ADA: return (style == SCE_ADA_COMMENTLINE); case SCLEX_ABAQUS: return (style == SCE_ABAQUS_COMMENT || style == SCE_ABAQUS_COMMENTBLOCK); case SCLEX_ASM: return (style == SCE_ASM_COMMENT || style == SCE_ASM_COMMENTBLOCK || style == SCE_ASM_COMMENTDIRECTIVE); case SCLEX_RUST: return (style == SCE_RUST_COMMENTBLOCK || style == SCE_RUST_COMMENTLINE || style == SCE_RUST_COMMENTBLOCKDOC || style == SCE_RUST_COMMENTLINEDOC); case SCLEX_COFFEESCRIPT: return (style == SCE_COFFEESCRIPT_COMMENTLINE || style == SCE_COFFEESCRIPT_COMMENTBLOCK || style == SCE_COFFEESCRIPT_VERBOSE_REGEX_COMMENT); case SCLEX_VERILOG: return (style == SCE_V_COMMENT || style == SCE_V_COMMENTLINE || style == SCE_V_COMMENTLINEBANG || style == SCE_V_COMMENT_WORD); case SCLEX_VHDL: return (style == SCE_VHDL_COMMENT || style == SCE_VHDL_COMMENTLINEBANG || style == SCE_VHDL_BLOCK_COMMENT); case SCLEX_BATCH: return (style == SCE_BAT_COMMENT); case SCLEX_CAML: return (style == SCE_CAML_COMMENT || style == SCE_CAML_COMMENT1 || style == SCE_CAML_COMMENT2 || style == SCE_CAML_COMMENT3); case SCLEX_ERLANG: return (style == SCE_ERLANG_COMMENT || style == SCE_ERLANG_COMMENT_FUNCTION || style == SCE_ERLANG_COMMENT_MODULE || style == SCE_ERLANG_COMMENT_DOC || style == SCE_ERLANG_COMMENT_DOC_MACRO); case SCLEX_FORTH: return (style == SCE_FORTH_COMMENT || style == SCE_FORTH_COMMENT_ML); case SCLEX_CSS: return (style == SCE_CSS_COMMENT); case SCLEX_DIFF: return (style == SCE_DIFF_COMMENT); case SCLEX_LISP: return (style == SCE_LISP_COMMENT || style == SCE_LISP_MULTI_COMMENT); case SCLEX_POWERSHELL: return (style == SCE_POWERSHELL_COMMENT || style == SCE_POWERSHELL_COMMENTSTREAM || style == SCE_POWERSHELL_COMMENTDOCKEYWORD); case SCLEX_TXT2TAGS: return (style == SCE_TXT2TAGS_COMMENT); case SCLEX_MARKDOWN: /* there is no comment type in those lexers, listing here just for completeness */ return FALSE; case SCLEX_GDSCRIPT: return (style == SCE_GD_COMMENTLINE || style == SCE_GD_COMMENTBLOCK); case SCLEX_AU3: return (style == SCE_AU3_COMMENT || style == SCE_AU3_COMMENTBLOCK); } return FALSE; } /** Checks whether the given style is normal code (not string, comment, preprocessor, etc). * * @param lexer Scintilla lexer type (@c SCLEX_*). * @param style Scintilla style (@c SCE_*). * * @return @c TRUE if the style is code, @c FALSE otherwise. */ GEANY_API_SYMBOL gboolean highlighting_is_code_style(gint lexer, gint style) { switch (lexer) { case SCLEX_CPP: { if (style == SCE_C_PREPROCESSOR) return FALSE; break; } case SCLEX_HASKELL: case SCLEX_LITERATEHASKELL: { if (style == SCE_HA_PREPROCESSOR) return FALSE; break; } case SCLEX_VERILOG: { if (style == SCE_V_PREPROCESSOR) return FALSE; break; } } return !(highlighting_is_comment_style(lexer, style) || highlighting_is_string_style(lexer, style)); } geany-2.0/src/geanyentryaction.h0000644000175000017500000000416014514252267013733 00000000000000/* * geanyentryaction.h - this file is part of Geany, a fast and lightweight IDE * * Copyright 2008 The Geany contributors * * This program 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; either version 2 of the License, or * (at your option) any later version. * * This program 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef GEANY_ENTRY_ACTION_H #define GEANY_ENTRY_ACTION_H 1 #include "gtkcompat.h" G_BEGIN_DECLS #define GEANY_ENTRY_ACTION_TYPE (geany_entry_action_get_type()) #define GEANY_ENTRY_ACTION(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),\ GEANY_ENTRY_ACTION_TYPE, GeanyEntryAction)) #define GEANY_ENTRY_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),\ GEANY_ENTRY_ACTION_TYPE, GeanyEntryActionClass)) #define IS_GEANY_ENTRY_ACTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),\ GEANY_ENTRY_ACTION_TYPE)) #define IS_GEANY_ENTRY_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),\ GEANY_ENTRY_ACTION_TYPE)) typedef struct _GeanyEntryAction GeanyEntryAction; typedef struct _GeanyEntryActionClass GeanyEntryActionClass; struct _GeanyEntryActionPrivate; struct _GeanyEntryAction { GtkAction parent; struct _GeanyEntryActionPrivate *priv; }; struct _GeanyEntryActionClass { GtkActionClass parent_class; }; GType geany_entry_action_get_type (void); GtkAction* geany_entry_action_new (const gchar *name, const gchar *label, const gchar *tooltip, gboolean numeric); GtkWidget* geany_entry_action_get_menu (GeanyEntryAction *action); G_END_DECLS #endif /* GEANY_ENTRY_ACTION_H */ geany-2.0/src/gtkcompat.h0000644000175000017500000000230514514252267012340 00000000000000/* * gtkcompat.h - this file is part of Geany, a fast and lightweight IDE * * Copyright 2012 The Geany contributors * * This program 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; either version 2 of the License, or * (at your option) any later version. * * This program 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /* Compatibility macros to support older GTK+ versions * * Although this file might not be useful anymore, it might be used by plugins * so it cannot be removed without care. */ #ifndef GTK_COMPAT_H #define GTK_COMPAT_H 1 #include #include #endif /* GTK_COMPAT_H */ geany-2.0/src/filetypes.h0000644000175000017500000001511114514252267012352 00000000000000/* * filetypes.h - this file is part of Geany, a fast and lightweight IDE * * Copyright 2005 The Geany contributors * * This program 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; either version 2 of the License, or * (at your option) any later version. * * This program 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef GEANY_FILETYPES_H #define GEANY_FILETYPES_H 1 #include "geany.h" /* for GEANY() macro */ #include "tm_parser.h" /* for TMParserType */ #include "gtkcompat.h" /* Needed by ScintillaWidget.h */ #include "Scintilla.h" /* Needed by ScintillaWidget.h */ #include "ScintillaWidget.h" /* for ScintillaObject */ #include G_BEGIN_DECLS /* Forward-declared to avoid including document.h since it includes this header */ struct GeanyDocument; /** IDs of known filetypes * * @ref filetypes will contain an item for each. Use GeanyData::filetypes_array to * determine the known filetypes at runtime */ typedef enum { GEANY_FILETYPES_NONE = 0, /* first filetype is always None & must be 0 */ GEANY_FILETYPES_PHP, GEANY_FILETYPES_BASIC, /* FreeBasic */ GEANY_FILETYPES_MATLAB, GEANY_FILETYPES_RUBY, GEANY_FILETYPES_LUA, GEANY_FILETYPES_GDSCRIPT, GEANY_FILETYPES_YAML, GEANY_FILETYPES_C, GEANY_FILETYPES_NSIS, GEANY_FILETYPES_GLSL, GEANY_FILETYPES_PO, GEANY_FILETYPES_MAKE, GEANY_FILETYPES_TCL, GEANY_FILETYPES_XML, GEANY_FILETYPES_CSS, GEANY_FILETYPES_REST, GEANY_FILETYPES_HASKELL, GEANY_FILETYPES_JAVA, GEANY_FILETYPES_CAML, GEANY_FILETYPES_AS, GEANY_FILETYPES_R, GEANY_FILETYPES_DIFF, GEANY_FILETYPES_HTML, GEANY_FILETYPES_PYTHON, GEANY_FILETYPES_CS, GEANY_FILETYPES_PERL, GEANY_FILETYPES_VALA, GEANY_FILETYPES_PASCAL, GEANY_FILETYPES_LATEX, GEANY_FILETYPES_ASM, GEANY_FILETYPES_CONF, GEANY_FILETYPES_HAXE, GEANY_FILETYPES_CPP, GEANY_FILETYPES_SH, GEANY_FILETYPES_FORTRAN, GEANY_FILETYPES_SQL, GEANY_FILETYPES_F77, GEANY_FILETYPES_DOCBOOK, GEANY_FILETYPES_D, GEANY_FILETYPES_JS, GEANY_FILETYPES_VHDL, GEANY_FILETYPES_ADA, GEANY_FILETYPES_CMAKE, GEANY_FILETYPES_MARKDOWN, GEANY_FILETYPES_TXT2TAGS, GEANY_FILETYPES_ABC, GEANY_FILETYPES_VERILOG, GEANY_FILETYPES_FORTH, GEANY_FILETYPES_LISP, GEANY_FILETYPES_ERLANG, GEANY_FILETYPES_COBOL, GEANY_FILETYPES_OBJECTIVEC, GEANY_FILETYPES_ASCIIDOC, GEANY_FILETYPES_ABAQUS, GEANY_FILETYPES_BATCH, GEANY_FILETYPES_POWERSHELL, GEANY_FILETYPES_RUST, GEANY_FILETYPES_COFFEESCRIPT, GEANY_FILETYPES_GO, GEANY_FILETYPES_ZEPHIR, GEANY_FILETYPES_BIBTEX, GEANY_FILETYPES_SMALLTALK, GEANY_FILETYPES_JULIA, GEANY_FILETYPES_AU3, /* ^ append items here */ GEANY_MAX_BUILT_IN_FILETYPES /* Don't use this, use filetypes_array->len instead */ } GeanyFiletypeID; /** @gironly * Filetype categories * * These are used to provide submenus for each category in the GUI */ typedef enum { GEANY_FILETYPE_GROUP_NONE, GEANY_FILETYPE_GROUP_COMPILED, GEANY_FILETYPE_GROUP_SCRIPT, GEANY_FILETYPE_GROUP_MARKUP, GEANY_FILETYPE_GROUP_MISC, GEANY_FILETYPE_GROUP_COUNT } GeanyFiletypeGroupID; /* Safe wrapper to get the id field of a possibly NULL filetype pointer. * This shouldn't be necessary since GeanyDocument::file_type is always non-NULL. */ #define FILETYPE_ID(filetype_ptr) \ (((filetype_ptr) != NULL) ? (filetype_ptr)->id : GEANY_FILETYPES_NONE) /** Represents a filetype. */ typedef struct GeanyFiletype { GeanyFiletypeID id; /**< Index in @ref filetypes. */ /* Represents the TMParserType of tagmanager (see the table * in src/tagmanager/tm_parser.h). */ TMParserType lang; /** Untranslated short name, such as "C", "None". * Must not be translated as it's used for hash table lookups - use * filetypes_get_display_name() instead. */ gchar *name; /** Shown in the file open dialog, such as "C source file". */ gchar *title; gchar *extension; /**< Default file extension for new files, or @c NULL. */ gchar **pattern; /**< Array of filename-matching wildcard strings. */ gchar *context_action_cmd; gchar *comment_open; gchar *comment_close; gboolean comment_use_indent; GeanyFiletypeGroupID group; gchar *error_regex_string; struct GeanyFiletype *lexer_filetype; gchar *mime_type; GIcon *icon; gchar *comment_single; /* single-line comment */ /* filetype indent settings, -1 if not set */ gint indent_type; gint indent_width; struct GeanyFiletypePrivate *priv; /* must be last, append fields before this item */ } GeanyFiletype; /** Wraps @ref GeanyData::filetypes_array so it can be used with C array syntax. * Example: filetypes[GEANY_FILETYPES_C]->name = ...; * @see filetypes_index(). */ #define filetypes ((GeanyFiletype **)GEANY(filetypes_array)->pdata) GeanyFiletype *filetypes_detect_from_file(const gchar *utf8_filename); GeanyFiletype *filetypes_lookup_by_name(const gchar *name); GeanyFiletype *filetypes_index(gint idx); const gchar *filetypes_get_display_name(GeanyFiletype *ft); const GSList *filetypes_get_sorted_by_name(void); #define GEANY_TYPE_FILETYPE (filetype_get_type()) GType filetype_get_type (void); #ifdef GEANY_PRIVATE extern GPtrArray *filetypes_array; extern GSList *filetypes_by_title; void filetypes_init(void); void filetypes_init_types(void); void filetypes_reload_extensions(void); void filetypes_reload(void); GeanyFiletype *filetypes_detect_from_document(struct GeanyDocument *doc); GeanyFiletype *filetypes_detect_from_extension(const gchar *utf8_filename); void filetypes_free_types(void); void filetypes_load_config(guint ft_id, gboolean reload); void filetypes_save_commands(GeanyFiletype *ft); void filetypes_select_radio_item(const GeanyFiletype *ft); GtkFileFilter *filetypes_create_file_filter(const GeanyFiletype *ft); GtkFileFilter *filetypes_create_file_filter_all_source(void); gboolean filetype_has_tags(GeanyFiletype *ft); gboolean filetypes_parse_error_message(GeanyFiletype *ft, const gchar *message, gchar **filename, gint *line); gboolean filetype_get_comment_open_close(const GeanyFiletype *ft, gboolean single_first, const gchar **co, const gchar **cc); #endif /* GEANY_PRIVATE */ G_END_DECLS #endif /* GEANY_FILETYPES_H */ geany-2.0/src/prefix.h0000644000175000017500000000670114514252267011650 00000000000000/* * BinReloc - a library for creating relocatable executables * Written by: Mike Hearn * Hongli Lai * http://autopackage.org/ * * This source code is public domain. You can relicense this code * under whatever license you want. * * See http://autopackage.org/docs/binreloc/ for * more information and how to use this. * * NOTE: if you're using C++ and are getting "undefined reference * to br_*", try renaming prefix.c to prefix.cpp */ #ifndef GEANY_PREFIX_H #define GEANY_PREFIX_H 1 /* * enrico - all the code below is only compiled and used if ENABLE_BINRELOC is set in config.h, * this only happens if configure option --enable-binreloc was used */ #ifdef ENABLE_BINRELOC #include G_BEGIN_DECLS /* WARNING, BEFORE YOU MODIFY PREFIX.C: * * If you make changes to any of the functions in prefix.c, you MUST * change the BR_NAMESPACE macro. * This way you can avoid symbol table conflicts with other libraries * that also happen to use BinReloc. * * Example: * #define BR_NAMESPACE(funcName) foobar_ ## funcName * --> expands br_locate to foobar_br_locate */ #undef BR_NAMESPACE #define BR_NAMESPACE(funcName) geany_ ## funcName #define br_thread_local_store BR_NAMESPACE(br_thread_local_store) #define br_locate BR_NAMESPACE(br_locate) #define br_locate_prefix BR_NAMESPACE(br_locate_prefix) #define br_prepend_prefix BR_NAMESPACE(br_prepend_prefix) #ifndef BR_NO_MACROS /* These are convience macros that replace the ones usually used in Autoconf/Automake projects */ #undef SELFPATH #undef PREFIX #undef PREFIXDIR #undef BINDIR #undef SBINDIR #undef DATADIR #undef LIBDIR #undef LIBEXECDIR #undef ETCDIR #undef SYSCONFDIR #undef CONFDIR #undef LOCALEDIR #undef GEANY_PREFIX #undef GEANY_DATADIR #undef GEANY_LIBDIR #undef GEANY_LIBEXECDIR #undef GEANY_DOCDIR #undef GEANY_LOCALEDIR #define SELFPATH (br_thread_local_store (br_locate ((void *) ""))) #define PREFIXDIR (br_thread_local_store (br_locate_prefix ((void *) ""))) #define BINDIR (br_thread_local_store (br_prepend_prefix ((void *) "", "/bin"))) #define SBINDIR (br_thread_local_store (br_prepend_prefix ((void *) "", "/sbin"))) #define LIBEXECDIR (br_thread_local_store (br_prepend_prefix ((void *) "", "/libexec"))) #define ETCDIR (br_thread_local_store (br_prepend_prefix ((void *) "", "/etc"))) #define SYSCONFDIR (br_thread_local_store (br_prepend_prefix ((void *) "", "/etc"))) #define CONFDIR (br_thread_local_store (br_prepend_prefix ((void *) "", "/etc"))) #define GEANY_PREFIX (br_thread_local_store (br_locate_prefix ((void *) ""))) #define GEANY_DATADIR (br_thread_local_store (br_prepend_prefix ((void *) "", "/share"))) #define GEANY_LIBDIR (br_thread_local_store (br_prepend_prefix ((void *) "", "/lib"))) #define GEANY_LIBEXECDIR (br_thread_local_store (br_prepend_prefix ((void *) "", "/libexec/geany"))) #define GEANY_DOCDIR (br_thread_local_store (br_prepend_prefix ((void *) "", "/share/doc/geany"))) #define GEANY_LOCALEDIR (br_thread_local_store (br_prepend_prefix ((void *) "", "/share/locale"))) #endif /* BR_NO_MACROS */ /* The following functions are used internally by BinReloc and shouldn't be used directly in applications. */ const char *br_thread_local_store (char *str); char *br_locate (void *symbol); char *br_locate_prefix (void *symbol); char *br_prepend_prefix (void *symbol, char *path); G_END_DECLS #endif /* ENABLE_BINRELOC */ #endif /* GEANY_PREFIX_H */ geany-2.0/src/callbacks.c0000644000175000017500000014453214514252267012272 00000000000000/* * callbacks.c - this file is part of Geany, a fast and lightweight IDE * * Copyright 2005 The Geany contributors * * This program 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; either version 2 of the License, or * (at your option) any later version. * * This program 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /* * Callbacks used by Glade. These are mainly in response to menu item and button events in the * main window. Callbacks not used by Glade should go elsewhere. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include "callbacks.h" #include "about.h" #include "app.h" #include "build.h" #include "dialogs.h" #include "documentprivate.h" #include "encodings.h" #include "filetypes.h" #include "geanyobject.h" #include "highlighting.h" #include "keybindings.h" #include "keyfile.h" #include "log.h" #include "main.h" #include "msgwindow.h" #include "navqueue.h" #include "plugins.h" #include "pluginutils.h" #include "prefs.h" #include "printing.h" #include "sciwrappers.h" #include "sidebar.h" #include "spawn.h" #ifdef HAVE_SOCKET # include "socket.h" #endif #include "support.h" #include "symbols.h" #include "templates.h" #include "toolbar.h" #include "tools.h" #include "ui_utils.h" #include "utils.h" #include "vte.h" #include #include #include #include #include #include #include /* represents the state at switching a notebook page(in the left treeviews widget), to not emit * the selection-changed signal from tv.tree_openfiles */ /*static gboolean switch_tv_notebook_page = FALSE; */ /* wrapper function to abort exit process if cancel button is pressed */ static gboolean on_window_delete_event(GtkWidget *widget, GdkEvent *event, gpointer gdata) { return !main_quit(); } /* * GUI callbacks */ void on_new1_activate(GtkMenuItem *menuitem, gpointer user_data) { keybindings_send_command(GEANY_KEY_GROUP_FILE, GEANY_KEYS_FILE_NEW); } /* create a new file and copy file content and properties */ static void on_clone1_activate(GtkMenuItem *menuitem, gpointer user_data) { GeanyDocument *old_doc = document_get_current(); if (old_doc) document_clone(old_doc); } void on_save1_activate(GtkMenuItem *menuitem, gpointer user_data) { GeanyDocument *doc = document_get_current(); if (doc != NULL) { document_save_file(doc, ui_prefs.allow_always_save); } } void on_save_as1_activate(GtkMenuItem *menuitem, gpointer user_data) { dialogs_show_save_as(); } void on_save_all1_activate(GtkMenuItem *menuitem, gpointer user_data) { guint i, max = (guint) gtk_notebook_get_n_pages(GTK_NOTEBOOK(main_widgets.notebook)); GeanyDocument *cur_doc = document_get_current(); guint count = 0; /* iterate over documents in tabs order */ for (i = 0; i < max; i++) { GeanyDocument *doc = document_get_from_page(i); if (! doc->changed) continue; if (document_save_file(doc, FALSE)) count++; } if (!count) return; ui_set_statusbar(FALSE, ngettext("%d file saved.", "%d files saved.", count), count); /* saving may have changed window title, sidebar for another doc, so update */ document_show_tab(cur_doc); sidebar_update_tag_list(cur_doc, TRUE); ui_set_window_title(cur_doc); } void on_close_all1_activate(GtkMenuItem *menuitem, gpointer user_data) { document_close_all(); } void on_close1_activate(GtkMenuItem *menuitem, gpointer user_data) { GeanyDocument *doc = document_get_current(); if (doc != NULL) document_close(doc); } void on_quit1_activate(GtkMenuItem *menuitem, gpointer user_data) { main_quit(); } static void on_file1_activate(GtkMenuItem *menuitem, gpointer user_data) { gtk_widget_set_sensitive(ui_widgets.recent_files_menuitem, g_queue_get_length(ui_prefs.recent_queue) > 0); /* hide Page setup when GTK printing is not used */ ui_widget_show_hide(ui_widgets.print_page_setup, printing_prefs.use_gtk_printing); } /* edit actions, c&p & co, from menu bar and from popup menu */ static void on_edit1_select(GtkMenuItem *menuitem, gpointer user_data) { GtkWidget *item; GeanyDocument *doc = document_get_current(); ui_update_menu_copy_items(doc); ui_update_insert_include_item(doc, 1); item = ui_lookup_widget(main_widgets.window, "plugin_preferences1"); #ifndef HAVE_PLUGINS gtk_widget_hide(item); #else gtk_widget_set_sensitive(item, plugins_have_preferences()); #endif } static void on_edit1_deselect(GtkMenuShell *menushell, gpointer user_data) { /* we re-enable items that were disabled in on_edit1_select() on menu popdown to * workaround mutli-layout keyboard issues in our keybinding handling code, so that * GTK's accelerator handling can catch them. * See https://github.com/geany/geany/issues/1368#issuecomment-273678207 */ ui_menu_copy_items_set_sensitive(TRUE); } void on_undo1_activate(GtkMenuItem *menuitem, gpointer user_data) { GeanyDocument *doc = document_get_current(); g_return_if_fail(doc != NULL); if (document_can_undo(doc)) { sci_cancel(doc->editor->sci); document_undo(doc); } } void on_redo1_activate(GtkMenuItem *menuitem, gpointer user_data) { GeanyDocument *doc = document_get_current(); g_return_if_fail(doc != NULL); if (document_can_redo(doc)) { sci_cancel(doc->editor->sci); document_redo(doc); } } void on_cut1_activate(GtkMenuItem *menuitem, gpointer user_data) { GtkWidget *focusw = gtk_window_get_focus(GTK_WINDOW(main_widgets.window)); if (GTK_IS_EDITABLE(focusw)) gtk_editable_cut_clipboard(GTK_EDITABLE(focusw)); else if (IS_SCINTILLA(focusw)) sci_cut(SCINTILLA(focusw)); else if (GTK_IS_TEXT_VIEW(focusw)) { GtkTextBuffer *buffer = gtk_text_view_get_buffer( GTK_TEXT_VIEW(focusw)); gtk_text_buffer_cut_clipboard(buffer, gtk_clipboard_get(GDK_NONE), TRUE); } } void on_copy1_activate(GtkMenuItem *menuitem, gpointer user_data) { GtkWidget *focusw = gtk_window_get_focus(GTK_WINDOW(main_widgets.window)); if (GTK_IS_EDITABLE(focusw)) gtk_editable_copy_clipboard(GTK_EDITABLE(focusw)); else if (IS_SCINTILLA(focusw)) sci_copy(SCINTILLA(focusw)); else if (GTK_IS_TEXT_VIEW(focusw)) { GtkTextBuffer *buffer = gtk_text_view_get_buffer( GTK_TEXT_VIEW(focusw)); gtk_text_buffer_copy_clipboard(buffer, gtk_clipboard_get(GDK_NONE)); } } void on_paste1_activate(GtkMenuItem *menuitem, gpointer user_data) { GtkWidget *focusw = gtk_window_get_focus(GTK_WINDOW(main_widgets.window)); if (GTK_IS_EDITABLE(focusw)) gtk_editable_paste_clipboard(GTK_EDITABLE(focusw)); else if (IS_SCINTILLA(focusw)) sci_paste(SCINTILLA(focusw)); else if (GTK_IS_TEXT_VIEW(focusw)) { GtkTextBuffer *buffer = gtk_text_view_get_buffer( GTK_TEXT_VIEW(focusw)); gtk_text_buffer_paste_clipboard(buffer, gtk_clipboard_get(GDK_NONE), NULL, TRUE); } } void on_delete1_activate(GtkMenuItem *menuitem, gpointer user_data) { GtkWidget *focusw = gtk_window_get_focus(GTK_WINDOW(main_widgets.window)); if (GTK_IS_EDITABLE(focusw)) gtk_editable_delete_selection(GTK_EDITABLE(focusw)); else if (IS_SCINTILLA(focusw) && sci_has_selection(SCINTILLA(focusw))) sci_clear(SCINTILLA(focusw)); else if (GTK_IS_TEXT_VIEW(focusw)) { GtkTextBuffer *buffer = gtk_text_view_get_buffer( GTK_TEXT_VIEW(focusw)); gtk_text_buffer_delete_selection(buffer, TRUE, TRUE); } } void on_preferences1_activate(GtkMenuItem *menuitem, gpointer user_data) { prefs_show_dialog(); } /* about menu item */ static void on_info1_activate(GtkMenuItem *menuitem, gpointer user_data) { about_dialog_show(); } /* open file */ void on_open1_activate(GtkMenuItem *menuitem, gpointer user_data) { dialogs_show_open_file(); } /* reload file */ void on_toolbutton_reload_clicked(GtkAction *action, gpointer user_data) { GeanyDocument *doc = document_get_current(); g_return_if_fail(doc != NULL); document_reload_prompt(doc, NULL); } /* reload all files */ void on_reload_all(GtkAction *action, gpointer user_data) { guint i; gint cur_page = gtk_notebook_get_current_page(GTK_NOTEBOOK(main_widgets.notebook)); if (!file_prefs.keep_edit_history_on_reload) { GeanyDocument *doc; foreach_document(i) { doc = documents[i]; if (doc->changed || document_can_undo(doc) || document_can_redo(doc)) { if (dialogs_show_question_full(NULL, _("_Reload"), GTK_STOCK_CANCEL, _("Changes detected, reloading all will lose any changes and history."), _("Are you sure you want to reload all files?"))) { break; // break the loop and continue with reloading below } else { return; // cancel reloading } } } } foreach_document(i) { if (! (documents[i]->file_name == NULL)) document_reload_force(documents[i], documents[i]->encoding); } gtk_notebook_set_current_page(GTK_NOTEBOOK(main_widgets.notebook), cur_page); } static void on_change_font1_activate(GtkMenuItem *menuitem, gpointer user_data) { dialogs_show_open_font(); } /* store text, clear search flags so we can use Search->Find Next/Previous */ static void setup_find(const gchar *text, gboolean backwards) { SETPTR(search_data.text, g_strdup(text)); SETPTR(search_data.original_text, g_strdup(text)); search_data.flags = 0; search_data.backwards = backwards; search_data.search_bar = TRUE; } static void do_toolbar_search(const gchar *text, gboolean incremental, gboolean backwards) { GeanyDocument *doc = document_get_current(); gboolean result; setup_find(text, backwards); result = document_search_bar_find(doc, search_data.text, incremental, backwards); if (search_data.search_bar) ui_set_search_entry_background(toolbar_get_widget_child_by_name("SearchEntry"), result); } /* search text */ void on_toolbar_search_entry_changed(GtkAction *action, const gchar *text, gpointer user_data) { do_toolbar_search(text, TRUE, FALSE); } /* search text */ void on_toolbar_search_entry_activate(GtkAction *action, const gchar *text, gpointer user_data) { do_toolbar_search(text, FALSE, GPOINTER_TO_INT(user_data)); } /* search text */ void on_toolbutton_search_clicked(GtkAction *action, gpointer user_data) { GeanyDocument *doc = document_get_current(); gboolean result; GtkWidget *entry = toolbar_get_widget_child_by_name("SearchEntry"); if (entry != NULL) { const gchar *text = gtk_entry_get_text(GTK_ENTRY(entry)); setup_find(text, FALSE); result = document_search_bar_find(doc, search_data.text, FALSE, FALSE); if (search_data.search_bar) ui_set_search_entry_background(entry, result); } else on_find1_activate(NULL, NULL); } void on_entry_tagfilter_changed(GtkAction *action, gpointer user_data) { GeanyDocument *doc = document_get_current(); GtkEntry *filter_entry; if (!doc) return; filter_entry = GTK_ENTRY(ui_lookup_widget(main_widgets.window, "entry_tagfilter")); g_free(doc->priv->tag_filter); doc->priv->tag_filter = g_strdup(gtk_entry_get_text(filter_entry)); /* make sure the tree is fully re-created so it appears correctly * after applying filter */ if (doc->priv->tag_store) gtk_tree_store_clear(doc->priv->tag_store); sidebar_update_tag_list(doc, TRUE); } void on_entry_tagfilter_icon_press(GtkEntry *entry, GtkEntryIconPosition icon_pos, GdkEvent *event, gpointer user_data) { if (event->button.button == 1) gtk_entry_set_text(entry, ""); } void on_entry_tagfilter_activate(GtkEntry *entry, gpointer user_data) { GeanyDocument *doc = document_get_current(); if (!doc) return; gtk_widget_grab_focus(doc->priv->tag_tree); } /* hides toolbar from toolbar popup menu */ static void on_hide_toolbar1_activate(GtkMenuItem *menuitem, gpointer user_data) { GtkWidget *tool_item = ui_lookup_widget(GTK_WIDGET(main_widgets.window), "menu_show_toolbar1"); gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(tool_item), FALSE); } /* zoom in from menu bar and popup menu */ void on_zoom_in1_activate(GtkMenuItem *menuitem, gpointer user_data) { GeanyDocument *doc = document_get_current(); g_return_if_fail(doc != NULL); sci_zoom_in(doc->editor->sci); } /* zoom out from menu bar and popup menu */ void on_zoom_out1_activate(GtkMenuItem *menuitem, gpointer user_data) { GeanyDocument *doc = document_get_current(); g_return_if_fail(doc != NULL); sci_zoom_out(doc->editor->sci); } void on_normal_size1_activate(GtkMenuItem *menuitem, gpointer user_data) { GeanyDocument *doc = document_get_current(); g_return_if_fail(doc != NULL); sci_zoom_off(doc->editor->sci); } /* Changes window-title after switching tabs and lots of other things. * note: using 'after' makes Scintilla redraw before the UI, appearing more responsive */ static void on_notebook1_switch_page_after(GtkNotebook *notebook, gpointer page, guint page_num, gpointer user_data) { GeanyDocument *doc; if (G_UNLIKELY(main_status.opening_session_files || main_status.closing_all)) return; doc = document_get_from_notebook_child(page); if (doc != NULL) { GtkEntry *filter_entry = GTK_ENTRY(ui_lookup_widget(main_widgets.window, "entry_tagfilter")); const gchar *entry_text = gtk_entry_get_text(filter_entry); sidebar_select_openfiles_item(doc); ui_save_buttons_toggle(doc->changed); ui_set_window_title(doc); ui_update_statusbar(doc, -1); ui_update_popup_reundo_items(doc); ui_document_show_hide(doc); /* update the document menu */ build_menu_update(doc); if (g_strcmp0(entry_text, doc->priv->tag_filter) != 0) { /* calls sidebar_update_tag_list() in on_entry_tagfilter_changed() */ gtk_entry_set_text(filter_entry, doc->priv->tag_filter); } else sidebar_update_tag_list(doc, TRUE); document_highlight_tags(doc); document_check_disk_status(doc, TRUE); #ifdef HAVE_VTE vte_cwd((doc->real_path != NULL) ? doc->real_path : doc->file_name, FALSE); #endif g_signal_emit_by_name(geany_object, "document-activate", doc); } } static void on_tv_notebook_switch_page(GtkNotebook *notebook, gpointer page, guint page_num, gpointer user_data) { /* suppress selection changed signal when switching to the open files list */ ignore_callback = TRUE; } static void on_tv_notebook_switch_page_after(GtkNotebook *notebook, gpointer page, guint page_num, gpointer user_data) { ignore_callback = FALSE; } static void convert_eol(gint mode) { GeanyDocument *doc = document_get_current(); g_return_if_fail(doc != NULL); /* sci_convert_eols() adds UNDO_SCINTILLA action in on_editor_notify(). * It is added to the undo stack before sci_convert_eols() finishes * so after adding UNDO_EOL, UNDO_EOL will be at the top of the stack * and UNDO_SCINTILLA below it. */ sci_convert_eols(doc->editor->sci, mode); document_undo_add(doc, UNDO_EOL, GINT_TO_POINTER(sci_get_eol_mode(doc->editor->sci))); sci_set_eol_mode(doc->editor->sci, mode); ui_update_statusbar(doc, -1); } static void on_crlf_activate(GtkCheckMenuItem *menuitem, gpointer user_data) { if (ignore_callback || ! gtk_check_menu_item_get_active(menuitem)) return; convert_eol(SC_EOL_CRLF); } static void on_lf_activate(GtkCheckMenuItem *menuitem, gpointer user_data) { if (ignore_callback || ! gtk_check_menu_item_get_active(menuitem)) return; convert_eol(SC_EOL_LF); } static void on_cr_activate(GtkCheckMenuItem *menuitem, gpointer user_data) { if (ignore_callback || ! gtk_check_menu_item_get_active(menuitem)) return; convert_eol(SC_EOL_CR); } void on_replace_tabs_activate(GtkMenuItem *menuitem, gpointer user_data) { GeanyDocument *doc = document_get_current(); g_return_if_fail(doc != NULL); editor_replace_tabs(doc->editor, FALSE); } gboolean toolbar_popup_menu(GtkWidget *widget, GdkEventButton *event, gpointer user_data) { if (event->button == 3) { gtk_menu_popup_at_pointer(GTK_MENU(ui_widgets.toolbar_menu), (GdkEvent *) event); return TRUE; } return FALSE; } void on_toggle_case1_activate(GtkMenuItem *menuitem, gpointer user_data) { GeanyDocument *doc = document_get_current(); ScintillaObject *sci; gboolean keep_sel = TRUE; g_return_if_fail(doc != NULL); sci = doc->editor->sci; if (! sci_has_selection(sci)) { keybindings_send_command(GEANY_KEY_GROUP_SELECT, GEANY_KEYS_SELECT_WORD); keep_sel = FALSE; } /* either we already had a selection or we created one for current word */ if (sci_has_selection(sci)) { gchar *result = NULL; gint cmd = SCI_LOWERCASE; gboolean rectsel = (gboolean) SSM(sci, SCI_SELECTIONISRECTANGLE, 0, 0); gchar *text = sci_get_selection_contents(sci); if (utils_str_has_upper(text)) { if (rectsel) cmd = SCI_LOWERCASE; else result = g_utf8_strdown(text, -1); } else { if (rectsel) cmd = SCI_UPPERCASE; else result = g_utf8_strup(text, -1); } if (result != NULL) { sci_replace_sel(sci, result); g_free(result); if (keep_sel) sci_set_selection_start(sci, sci_get_current_position(sci) - strlen(text)); } else sci_send_command(sci, cmd); g_free(text); } } static void on_show_toolbar1_toggled(GtkCheckMenuItem *checkmenuitem, gpointer user_data) { if (ignore_callback) return; toolbar_prefs.visible = (toolbar_prefs.visible) ? FALSE : TRUE;; ui_widget_show_hide(GTK_WIDGET(main_widgets.toolbar), toolbar_prefs.visible); } static void on_fullscreen1_toggled(GtkCheckMenuItem *checkmenuitem, gpointer user_data) { if (ignore_callback) return; ui_prefs.fullscreen = (ui_prefs.fullscreen) ? FALSE : TRUE; ui_set_fullscreen(); } static void on_show_messages_window1_toggled(GtkCheckMenuItem *checkmenuitem, gpointer user_data) { if (ignore_callback) return; ui_prefs.msgwindow_visible = (ui_prefs.msgwindow_visible) ? FALSE : TRUE; msgwin_show_hide(ui_prefs.msgwindow_visible); } static void on_menu_color_schemes_activate(GtkImageMenuItem *imagemenuitem, gpointer user_data) { highlighting_show_color_scheme_dialog(); } static void on_markers_margin1_toggled(GtkCheckMenuItem *checkmenuitem, gpointer user_data) { if (ignore_callback) return; editor_prefs.show_markers_margin = ! editor_prefs.show_markers_margin; ui_toggle_editor_features(GEANY_EDITOR_SHOW_MARKERS_MARGIN); } static void on_show_line_numbers1_toggled(GtkCheckMenuItem *checkmenuitem, gpointer user_data) { if (ignore_callback) return; editor_prefs.show_linenumber_margin = ! editor_prefs.show_linenumber_margin; ui_toggle_editor_features(GEANY_EDITOR_SHOW_LINE_NUMBERS); } static void on_menu_show_white_space1_toggled(GtkCheckMenuItem *checkmenuitem, gpointer user_data) { if (ignore_callback) return; editor_prefs.show_white_space = ! editor_prefs.show_white_space; ui_toggle_editor_features(GEANY_EDITOR_SHOW_WHITE_SPACE); } static void on_menu_show_line_endings1_toggled(GtkCheckMenuItem *checkmenuitem, gpointer user_data) { if (ignore_callback) return; editor_prefs.show_line_endings = ! editor_prefs.show_line_endings; ui_toggle_editor_features(GEANY_EDITOR_SHOW_LINE_ENDINGS); } static void on_menu_show_indentation_guides1_toggled(GtkCheckMenuItem *checkmenuitem, gpointer user_data) { if (ignore_callback) return; editor_prefs.show_indent_guide = ! editor_prefs.show_indent_guide; ui_toggle_editor_features(GEANY_EDITOR_SHOW_INDENTATION_GUIDES); } void on_line_wrapping1_toggled(GtkCheckMenuItem *checkmenuitem, gpointer user_data) { if (! ignore_callback) { GeanyDocument *doc = document_get_current(); g_return_if_fail(doc != NULL); editor_set_line_wrapping(doc->editor, ! doc->editor->line_wrapping); } } static void on_set_file_readonly1_toggled(GtkCheckMenuItem *checkmenuitem, gpointer user_data) { if (! ignore_callback) { GeanyDocument *doc = document_get_current(); g_return_if_fail(doc != NULL); doc->readonly = ! doc->readonly; sci_set_readonly(doc->editor->sci, doc->readonly); ui_update_tab_status(doc); ui_update_statusbar(doc, -1); } } static void on_use_auto_indentation1_toggled(GtkCheckMenuItem *checkmenuitem, gpointer user_data) { if (! ignore_callback) { GeanyDocument *doc = document_get_current(); g_return_if_fail(doc != NULL); doc->editor->auto_indent = ! doc->editor->auto_indent; } } static void find_usage(gboolean in_session) { GeanyFindFlags flags; gchar *search_text; GeanyDocument *doc = document_get_current(); g_return_if_fail(doc != NULL); if (sci_has_selection(doc->editor->sci)) { /* take selected text if there is a selection */ search_text = sci_get_selection_contents(doc->editor->sci); flags = GEANY_FIND_MATCHCASE; } else { editor_find_current_word_sciwc(doc->editor, -1, editor_info.current_word, GEANY_MAX_WORD_LENGTH); search_text = g_strdup(editor_info.current_word); flags = GEANY_FIND_MATCHCASE | GEANY_FIND_WHOLEWORD; } search_find_usage(search_text, search_text, flags, in_session); g_free(search_text); } void on_find_document_usage1_activate(GtkMenuItem *menuitem, gpointer user_data) { find_usage(FALSE); } void on_find_usage1_activate(GtkMenuItem *menuitem, gpointer user_data) { find_usage(TRUE); } static void goto_tag(gboolean definition) { GeanyDocument *doc = document_get_current(); g_return_if_fail(doc != NULL); /* update cursor pos for navigating back afterwards */ if (!sci_has_selection(doc->editor->sci)) sci_set_current_position(doc->editor->sci, editor_info.click_pos, FALSE); /* use the keybinding callback as it checks for selections as well as current word */ if (definition) keybindings_send_command(GEANY_KEY_GROUP_GOTO, GEANY_KEYS_GOTO_TAGDEFINITION); else keybindings_send_command(GEANY_KEY_GROUP_GOTO, GEANY_KEYS_GOTO_TAGDECLARATION); } static void on_goto_tag_definition1(GtkMenuItem *menuitem, gpointer user_data) { goto_tag(TRUE); } static void on_goto_tag_declaration1(GtkMenuItem *menuitem, gpointer user_data) { goto_tag(FALSE); } static void on_count_words1_activate(GtkMenuItem *menuitem, gpointer user_data) { tools_word_count(); } void on_show_color_chooser1_activate(GtkMenuItem *menuitem, gpointer user_data) { gchar colour[9]; GeanyDocument *doc = document_get_current(); gint pos; g_return_if_fail(doc != NULL); pos = sci_get_current_position(doc->editor->sci); editor_find_current_word(doc->editor, pos, colour, sizeof colour, GEANY_WORDCHARS"#"); tools_color_chooser(colour); } void on_toolbutton_compile_clicked(GtkAction *action, gpointer user_data) { keybindings_send_command(GEANY_KEY_GROUP_BUILD, GEANY_KEYS_BUILD_COMPILE); } void on_find1_activate(GtkMenuItem *menuitem, gpointer user_data) { search_show_find_dialog(); } void on_find_next1_activate(GtkMenuItem *menuitem, gpointer user_data) { search_find_again(FALSE); } void on_find_previous1_activate(GtkMenuItem *menuitem, gpointer user_data) { if (search_data.flags & GEANY_FIND_REGEXP) /* Can't reverse search order for a regex (find next ignores search backwards) */ utils_beep(); else search_find_again(TRUE); } void on_find_nextsel1_activate(GtkMenuItem *menuitem, gpointer user_data) { search_find_selection(document_get_current(), FALSE); } void on_find_prevsel1_activate(GtkMenuItem *menuitem, gpointer user_data) { search_find_selection(document_get_current(), TRUE); } void on_replace1_activate(GtkMenuItem *menuitem, gpointer user_data) { search_show_replace_dialog(); } void on_find_in_files1_activate(GtkMenuItem *menuitem, gpointer user_data) { search_show_find_in_files_dialog(NULL); } void on_go_to_line_activate(GtkMenuItem *menuitem, gpointer user_data) { static gchar value[16] = ""; gchar *result; result = dialogs_show_input_goto_line( _("Go to Line"), GTK_WINDOW(main_widgets.window), _("Enter the line you want to go to:"), value); if (result != NULL) { on_toolbutton_goto_entry_activate(NULL, result, NULL); /* remember value for future calls */ g_snprintf(value, sizeof(value), "%s", result); g_free(result); } } void on_toolbutton_goto_entry_activate(GtkAction *action, const gchar *text, gpointer user_data) { GeanyDocument *doc = document_get_current(); g_return_if_fail(doc != NULL); gint line_no = atoi(text); gboolean offset = (*text == '+' || *text == '-'); if (! editor_goto_line(doc->editor, line_no, offset)) utils_beep(); else keybindings_send_command(GEANY_KEY_GROUP_FOCUS, GEANY_KEYS_FOCUS_EDITOR); } void on_toolbutton_goto_clicked(GtkAction *action, gpointer user_data) { GtkWidget *entry = toolbar_get_widget_child_by_name("GotoEntry"); if (entry != NULL) { const gchar *text = gtk_entry_get_text(GTK_ENTRY(entry)); on_toolbutton_goto_entry_activate(NULL, text, NULL); } else on_go_to_line_activate(NULL, NULL); } void on_help1_activate(GtkMenuItem *menuitem, gpointer user_data) { gchar *uri; uri = utils_get_help_url(NULL); utils_open_browser(uri); g_free(uri); } static void on_help_shortcuts1_activate(GtkMenuItem *menuitem, gpointer user_data) { keybindings_show_shortcuts(); } static void on_website1_activate(GtkMenuItem *menuitem, gpointer user_data) { utils_open_browser(GEANY_HOMEPAGE); } static void on_help_menu_item_donate_activate(GtkMenuItem *item, gpointer user_data) { utils_open_browser(GEANY_DONATE); } static void on_help_menu_item_wiki_activate(GtkMenuItem *item, gpointer user_data) { utils_open_browser(GEANY_WIKI); } static void on_help_menu_item_bug_report_activate(GtkMenuItem *item, gpointer user_data) { utils_open_browser(GEANY_BUG_REPORT); } static void on_comments_function_activate(GtkMenuItem *menuitem, gpointer user_data) { GeanyDocument *doc = document_get_current(); gchar *text; const gchar *cur_tag = NULL; gint line = -1, pos = 0; if (doc == NULL || doc->file_type == NULL) { ui_set_statusbar(FALSE, _("Please set the filetype for the current file before using this function.")); return; } /* symbols_get_current_function returns -1 on failure, so sci_get_position_from_line * returns the current position, so it should be safe */ line = symbols_get_current_function(doc, &cur_tag); pos = sci_get_position_from_line(doc->editor->sci, line); text = templates_get_template_function(doc, cur_tag); sci_start_undo_action(doc->editor->sci); sci_insert_text(doc->editor->sci, pos, text); sci_end_undo_action(doc->editor->sci); g_free(text); } static void insert_multiline_comment(GeanyDocument *doc, gint pos) { g_return_if_fail(doc != NULL); g_return_if_fail(pos == -1 || pos >= 0); if (doc->file_type == NULL) { ui_set_statusbar(FALSE, _("Please set the filetype for the current file before using this function.")); return; } if (doc->file_type->comment_open || doc->file_type->comment_single) { /* editor_insert_multiline_comment() uses editor_info.click_pos */ if (pos == -1) editor_info.click_pos = sci_get_current_position(doc->editor->sci); else editor_info.click_pos = pos; editor_insert_multiline_comment(doc->editor); } else utils_beep(); } static void on_comments_multiline_activate(GtkMenuItem *menuitem, gpointer user_data) { insert_multiline_comment(document_get_current(), editor_info.click_pos); } static void on_menu_comments_multiline_activate(GtkMenuItem *menuitem, gpointer user_data) { insert_multiline_comment(document_get_current(), -1); } static void insert_comment_template(GeanyDocument *doc, gint pos, guint template) { gchar *text; g_return_if_fail(doc != NULL); g_return_if_fail(pos == -1 || pos >= 0); g_return_if_fail(template < GEANY_MAX_TEMPLATES); if (pos == -1) pos = sci_get_current_position(doc->editor->sci); text = templates_get_template_licence(doc, template); sci_start_undo_action(doc->editor->sci); sci_insert_text(doc->editor->sci, pos, text); sci_end_undo_action(doc->editor->sci); g_free(text); } static void on_comments_gpl_activate(GtkMenuItem *menuitem, gpointer user_data) { insert_comment_template(document_get_current(), editor_info.click_pos, GEANY_TEMPLATE_GPL); } static void on_menu_comments_gpl_activate(GtkMenuItem *menuitem, gpointer user_data) { insert_comment_template(document_get_current(), -1, GEANY_TEMPLATE_GPL); } static void on_comments_bsd_activate(GtkMenuItem *menuitem, gpointer user_data) { insert_comment_template(document_get_current(), editor_info.click_pos, GEANY_TEMPLATE_BSD); } static void on_menu_comments_bsd_activate(GtkMenuItem *menuitem, gpointer user_data) { insert_comment_template(document_get_current(), -1, GEANY_TEMPLATE_BSD); } static void on_comments_changelog_activate(GtkMenuItem *menuitem, gpointer user_data) { GeanyDocument *doc = document_get_current(); gchar *text; g_return_if_fail(doc != NULL); text = templates_get_template_changelog(doc); sci_start_undo_action(doc->editor->sci); sci_insert_text(doc->editor->sci, 0, text); /* sets the cursor to the right position to type the changelog text, * the template has 21 chars + length of name and email */ sci_goto_pos(doc->editor->sci, 21 + strlen(template_prefs.developer) + strlen(template_prefs.mail), TRUE); sci_end_undo_action(doc->editor->sci); g_free(text); } static void on_comments_fileheader_activate(GtkMenuItem *menuitem, gpointer user_data) { GeanyDocument *doc = document_get_current(); gchar *text; const gchar *fname; GeanyFiletype *ft; g_return_if_fail(doc != NULL); ft = doc->file_type; fname = doc->file_name; text = templates_get_template_fileheader(FILETYPE_ID(ft), fname); sci_start_undo_action(doc->editor->sci); sci_insert_text(doc->editor->sci, 0, text); sci_goto_pos(doc->editor->sci, 0, FALSE); sci_end_undo_action(doc->editor->sci); g_free(text); } void on_file_properties_activate(GtkMenuItem *menuitem, gpointer user_data) { GeanyDocument *doc = document_get_current(); g_return_if_fail(doc != NULL); dialogs_show_file_properties(doc); } static void on_menu_fold_all1_activate(GtkMenuItem *menuitem, gpointer user_data) { GeanyDocument *doc = document_get_current(); g_return_if_fail(doc != NULL); editor_fold_all(doc->editor); } static void on_menu_unfold_all1_activate(GtkMenuItem *menuitem, gpointer user_data) { GeanyDocument *doc = document_get_current(); g_return_if_fail(doc != NULL); editor_unfold_all(doc->editor); } void on_toolbutton_run_clicked(GtkAction *action, gpointer user_data) { keybindings_send_command(GEANY_KEY_GROUP_BUILD, GEANY_KEYS_BUILD_RUN); } void on_menu_remove_indicators1_activate(GtkMenuItem *menuitem, gpointer user_data) { GeanyDocument *doc = document_get_current(); g_return_if_fail(doc != NULL); editor_indicator_clear(doc->editor, GEANY_INDICATOR_ERROR); } void on_print1_activate(GtkMenuItem *menuitem, gpointer user_data) { GeanyDocument *doc = document_get_current(); g_return_if_fail(doc != NULL); printing_print_doc(doc); } void on_menu_select_all1_activate(GtkMenuItem *menuitem, gpointer user_data) { GtkWidget *focusw = gtk_window_get_focus(GTK_WINDOW(main_widgets.window)); /* special case for Select All in the scribble widget */ if (GTK_IS_TEXT_VIEW(focusw)) { g_signal_emit_by_name(focusw, "select-all", TRUE); } /* special case for Select All in the VTE widget */ #ifdef HAVE_VTE else if (vte_info.have_vte && focusw == vte_config.vte) { vte_select_all(); } #endif else if (GTK_IS_EDITABLE(focusw)) { gtk_editable_select_region(GTK_EDITABLE(focusw), 0, -1); } else if (IS_SCINTILLA(focusw)) { sci_select_all(SCINTILLA(focusw)); } } void on_menu_show_sidebar1_toggled(GtkCheckMenuItem *checkmenuitem, gpointer user_data) { if (ignore_callback) return; ui_prefs.sidebar_visible = ! ui_prefs.sidebar_visible; /* show built-in tabs if no tabs visible */ if (ui_prefs.sidebar_visible && ! interface_prefs.sidebar_openfiles_visible && ! interface_prefs.sidebar_symbol_visible && gtk_notebook_get_n_pages(GTK_NOTEBOOK(main_widgets.sidebar_notebook)) <= 2) { interface_prefs.sidebar_openfiles_visible = TRUE; interface_prefs.sidebar_symbol_visible = TRUE; } /* if window has input focus, set it back to the editor before toggling off */ if (! ui_prefs.sidebar_visible && gtk_container_get_focus_child(GTK_CONTAINER(main_widgets.sidebar_notebook)) != NULL) { keybindings_send_command(GEANY_KEY_GROUP_FOCUS, GEANY_KEYS_FOCUS_EDITOR); } ui_sidebar_show_hide(); } static void on_menu_write_unicode_bom1_toggled(GtkCheckMenuItem *checkmenuitem, gpointer user_data) { if (! ignore_callback) { GeanyDocument *doc = document_get_current(); g_return_if_fail(doc != NULL); if (doc->readonly) { utils_beep(); return; } document_undo_add(doc, UNDO_BOM, GINT_TO_POINTER(doc->has_bom)); doc->has_bom = ! doc->has_bom; ui_update_statusbar(doc, -1); } } void on_menu_comment_line1_activate(GtkMenuItem *menuitem, gpointer user_data) { GeanyDocument *doc = document_get_current(); g_return_if_fail(doc != NULL); editor_do_comment(doc->editor, -1, FALSE, FALSE, TRUE); } void on_menu_uncomment_line1_activate(GtkMenuItem *menuitem, gpointer user_data) { GeanyDocument *doc = document_get_current(); g_return_if_fail(doc != NULL); editor_do_uncomment(doc->editor, -1, FALSE); } void on_menu_toggle_line_commentation1_activate(GtkMenuItem *menuitem, gpointer user_data) { GeanyDocument *doc = document_get_current(); g_return_if_fail(doc != NULL); editor_do_comment_toggle(doc->editor); } void on_menu_increase_indent1_activate(GtkMenuItem *menuitem, gpointer user_data) { GeanyDocument *doc = document_get_current(); g_return_if_fail(doc != NULL); editor_indent(doc->editor, TRUE); } void on_menu_decrease_indent1_activate(GtkMenuItem *menuitem, gpointer user_data) { GeanyDocument *doc = document_get_current(); g_return_if_fail(doc != NULL); editor_indent(doc->editor, FALSE); } void on_next_message1_activate(GtkMenuItem *menuitem, gpointer user_data) { if (! ui_tree_view_find_next(GTK_TREE_VIEW(msgwindow.tree_msg), msgwin_goto_messages_file_line)) ui_set_statusbar(FALSE, _("No more message items.")); } void on_previous_message1_activate(GtkMenuItem *menuitem, gpointer user_data) { if (! ui_tree_view_find_previous(GTK_TREE_VIEW(msgwindow.tree_msg), msgwin_goto_messages_file_line)) ui_set_statusbar(FALSE, _("No more message items.")); } void on_project_new1_activate(GtkMenuItem *menuitem, gpointer user_data) { project_new(FALSE); } void on_project_new_from_folder1_activate(GtkMenuItem *menuitem, gpointer user_data) { project_new(TRUE); } void on_project_open1_activate(GtkMenuItem *menuitem, gpointer user_data) { project_open(); } void on_project_close1_activate(GtkMenuItem *menuitem, gpointer user_data) { project_close(TRUE); } void on_project_properties1_activate(GtkMenuItem *menuitem, gpointer user_data) { project_properties(); } static void on_menu_project1_activate(GtkMenuItem *menuitem, gpointer user_data) { static GtkWidget *item_close = NULL; static GtkWidget *item_properties = NULL; if (item_close == NULL) { item_close = ui_lookup_widget(main_widgets.window, "project_close1"); item_properties = ui_lookup_widget(main_widgets.window, "project_properties1"); } gtk_widget_set_sensitive(item_close, (app->project != NULL)); gtk_widget_set_sensitive(item_properties, (app->project != NULL)); gtk_widget_set_sensitive(ui_widgets.recent_projects_menuitem, g_queue_get_length(ui_prefs.recent_projects_queue) > 0); } void on_menu_open_selected_file1_activate(GtkMenuItem *menuitem, gpointer user_data) { GeanyDocument *doc = document_get_current(); gchar *sel = NULL; const gchar *wc; #ifdef G_OS_WIN32 wc = GEANY_WORDCHARS "./-" "\\"; #else wc = GEANY_WORDCHARS "./-"; #endif g_return_if_fail(doc != NULL); sel = editor_get_default_selection(doc->editor, TRUE, wc); SETPTR(sel, utils_get_locale_from_utf8(sel)); if (sel != NULL) { gchar *filename = NULL; if (g_path_is_absolute(sel)) filename = g_strdup(sel); else { /* relative filename, add the path of the current file */ gchar *path; path = utils_get_current_file_dir_utf8(); SETPTR(path, utils_get_locale_from_utf8(path)); if (!path) path = g_get_current_dir(); filename = g_build_path(G_DIR_SEPARATOR_S, path, sel, NULL); if (! g_file_test(filename, G_FILE_TEST_EXISTS) && app->project != NULL && !EMPTY(app->project->base_path)) { /* try the project's base path */ SETPTR(path, project_get_base_path()); SETPTR(path, utils_get_locale_from_utf8(path)); SETPTR(filename, g_build_path(G_DIR_SEPARATOR_S, path, sel, NULL)); } g_free(path); #ifdef G_OS_UNIX if (! g_file_test(filename, G_FILE_TEST_EXISTS)) SETPTR(filename, g_build_path(G_DIR_SEPARATOR_S, "/usr/local/include", sel, NULL)); if (! g_file_test(filename, G_FILE_TEST_EXISTS)) SETPTR(filename, g_build_path(G_DIR_SEPARATOR_S, "/usr/include", sel, NULL)); #endif } if (g_file_test(filename, G_FILE_TEST_EXISTS)) document_open_file(filename, FALSE, NULL, NULL); else { SETPTR(sel, utils_get_utf8_from_locale(sel)); ui_set_statusbar(TRUE, _("Could not open file %s (File not found)"), sel); } g_free(filename); g_free(sel); } } void on_remove_markers1_activate(GtkMenuItem *menuitem, gpointer user_data) { GeanyDocument *doc = document_get_current(); g_return_if_fail(doc != NULL); sci_marker_delete_all(doc->editor->sci, 0); /* delete the yellow tag marker */ sci_marker_delete_all(doc->editor->sci, 1); /* delete user markers */ editor_indicator_clear(doc->editor, GEANY_INDICATOR_SEARCH); } static void on_load_tags1_activate(GtkMenuItem *menuitem, gpointer user_data) { symbols_show_load_tags_dialog(); } void on_context_action1_activate(GtkMenuItem *menuitem, gpointer user_data) { gchar *word, *command; GError *error = NULL; GeanyDocument *doc = document_get_current(); const gchar *check_msg; g_return_if_fail(doc != NULL); if (sci_has_selection(doc->editor->sci)) { /* take selected text if there is a selection */ word = sci_get_selection_contents(doc->editor->sci); } else { word = g_strdup(editor_info.current_word); } /* use the filetype specific command if available, fallback to global command otherwise */ if (doc->file_type != NULL && !EMPTY(doc->file_type->context_action_cmd)) { command = g_strdup(doc->file_type->context_action_cmd); check_msg = _("Check the path setting in Filetype configuration."); } else { command = g_strdup(tool_prefs.context_action_cmd); check_msg = _("Check the path setting in Preferences."); } /* substitute the wildcard %s and run the command if it is non empty */ if (G_LIKELY(!EMPTY(command))) { gchar *command_line = g_strdup(command); utils_str_replace_all(&command_line, "%s", word); if (!spawn_async(NULL, command_line, NULL, NULL, NULL, &error)) { /* G_SHELL_ERROR is parsing error, it may be caused by %s word with quotes */ ui_set_statusbar(TRUE, _("Cannot execute context action command \"%s\": %s. %s"), error->domain == G_SHELL_ERROR ? command_line : command, error->message, check_msg); g_error_free(error); } g_free(command_line); } else { ui_set_statusbar(TRUE, _("No context action set.")); } g_free(word); g_free(command); } void on_menu_toggle_all_additional_widgets1_activate(GtkMenuItem *menuitem, gpointer user_data) { static gint hide_all = -1; GtkCheckMenuItem *msgw = GTK_CHECK_MENU_ITEM( ui_lookup_widget(main_widgets.window, "menu_show_messages_window1")); GtkCheckMenuItem *toolbari = GTK_CHECK_MENU_ITEM( ui_lookup_widget(main_widgets.window, "menu_show_toolbar1")); /* get the initial state (necessary if Geany was closed with hide_all = TRUE) */ if (G_UNLIKELY(hide_all == -1)) { if (! gtk_check_menu_item_get_active(msgw) && ! interface_prefs.show_notebook_tabs && ! gtk_check_menu_item_get_active(toolbari)) { hide_all = TRUE; } else hide_all = FALSE; } hide_all = ! hide_all; /* toggle */ if (hide_all) { if (gtk_check_menu_item_get_active(msgw)) gtk_check_menu_item_set_active(msgw, ! gtk_check_menu_item_get_active(msgw)); interface_prefs.show_notebook_tabs = FALSE; gtk_notebook_set_show_tabs(GTK_NOTEBOOK(main_widgets.notebook), interface_prefs.show_notebook_tabs); ui_statusbar_showhide(FALSE); if (gtk_check_menu_item_get_active(toolbari)) gtk_check_menu_item_set_active(toolbari, ! gtk_check_menu_item_get_active(toolbari)); } else { if (! gtk_check_menu_item_get_active(msgw)) gtk_check_menu_item_set_active(msgw, ! gtk_check_menu_item_get_active(msgw)); interface_prefs.show_notebook_tabs = TRUE; gtk_notebook_set_show_tabs(GTK_NOTEBOOK(main_widgets.notebook), interface_prefs.show_notebook_tabs); ui_statusbar_showhide(TRUE); if (! gtk_check_menu_item_get_active(toolbari)) gtk_check_menu_item_set_active(toolbari, ! gtk_check_menu_item_get_active(toolbari)); } } void on_toolbutton_forward_activate(GtkAction *menuitem, gpointer user_data) { navqueue_go_forward(); } void on_toolbutton_back_activate(GtkAction *menuitem, gpointer user_data) { navqueue_go_back(); } gboolean on_motion_event(GtkWidget *widget, GdkEventMotion *event, gpointer user_data) { if (prefs.auto_focus && ! gtk_widget_has_focus(widget)) gtk_widget_grab_focus(widget); return FALSE; } static void set_indent_type(GtkCheckMenuItem *menuitem, GeanyIndentType type) { GeanyDocument *doc; if (ignore_callback || ! gtk_check_menu_item_get_active(menuitem)) return; doc = document_get_current(); g_return_if_fail(doc != NULL); editor_set_indent(doc->editor, type, doc->editor->indent_width); ui_update_statusbar(doc, -1); } static void on_tabs1_activate(GtkCheckMenuItem *menuitem, gpointer user_data) { set_indent_type(menuitem, GEANY_INDENT_TYPE_TABS); } static void on_spaces1_activate(GtkCheckMenuItem *menuitem, gpointer user_data) { set_indent_type(menuitem, GEANY_INDENT_TYPE_SPACES); } static void on_tabs_and_spaces1_activate(GtkCheckMenuItem *menuitem, gpointer user_data) { set_indent_type(menuitem, GEANY_INDENT_TYPE_BOTH); } static void on_strip_trailing_spaces1_activate(GtkMenuItem *menuitem, gpointer user_data) { GeanyDocument *doc; if (ignore_callback) return; doc = document_get_current(); g_return_if_fail(doc != NULL); editor_strip_trailing_spaces(doc->editor, FALSE); } static void on_page_setup1_activate(GtkMenuItem *menuitem, gpointer user_data) { printing_page_setup_gtk(); } gboolean on_escape_key_press_event(GtkWidget *widget, GdkEventKey *event, gpointer user_data) { guint state = keybindings_get_modifiers(event->state); /* make pressing escape in the sidebar and toolbar focus the editor */ if (event->keyval == GDK_KEY_Escape && state == 0) { keybindings_send_command(GEANY_KEY_GROUP_FOCUS, GEANY_KEYS_FOCUS_EDITOR); return TRUE; } return FALSE; } void on_line_breaking1_activate(GtkMenuItem *menuitem, gpointer user_data) { GeanyDocument *doc; if (ignore_callback) return; doc = document_get_current(); g_return_if_fail(doc != NULL); doc->editor->line_breaking = !doc->editor->line_breaking; } void on_replace_spaces_activate(GtkMenuItem *menuitem, gpointer user_data) { GeanyDocument *doc = document_get_current(); g_return_if_fail(doc != NULL); editor_replace_spaces(doc->editor, FALSE); } static void on_search1_activate(GtkMenuItem *menuitem, gpointer user_data) { GtkWidget *next_message = ui_lookup_widget(main_widgets.window, "next_message1"); GtkWidget *previous_message = ui_lookup_widget(main_widgets.window, "previous_message1"); gboolean have_messages; /* enable commands if the messages window has any items */ have_messages = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(msgwindow.store_msg), NULL) > 0; gtk_widget_set_sensitive(next_message, have_messages); gtk_widget_set_sensitive(previous_message, have_messages); } /* simple implementation (vs. close all which doesn't close documents if cancelled), * if user_data is set, it is the GeanyDocument to keep */ void on_close_other_documents1_activate(GtkMenuItem *menuitem, gpointer user_data) { guint i; GeanyDocument *cur_doc = user_data; if (cur_doc == NULL) cur_doc = document_get_current(); for (i = 0; i < documents_array->len; i++) { GeanyDocument *doc = documents[i]; if (doc == cur_doc || ! doc->is_valid) continue; if (! document_close(doc)) break; } } static void on_menu_reload_configuration1_activate(GtkMenuItem *menuitem, gpointer user_data) { main_reload_configuration(); } static void on_debug_messages1_activate(GtkMenuItem *menuitem, gpointer user_data) { log_show_debug_messages_dialog(); } void on_send_selection_to_vte1_activate(GtkMenuItem *menuitem, gpointer user_data) { #ifdef HAVE_VTE if (vte_info.have_vte) vte_send_selection_to_vte(); #endif } static gboolean on_window_state_event(GtkWidget *widget, GdkEventWindowState *event, gpointer user_data) { if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) { static GtkWidget *menuitem = NULL; if (menuitem == NULL) menuitem = ui_lookup_widget(widget, "menu_fullscreen1"); ignore_callback = TRUE; ui_prefs.fullscreen = (event->new_window_state & GDK_WINDOW_STATE_FULLSCREEN) ? TRUE : FALSE; gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem), ui_prefs.fullscreen); ignore_callback = FALSE; } return FALSE; } static void show_notebook_page(const gchar *notebook_name, const gchar *page_name) { GtkWidget *widget; GtkNotebook *notebook; widget = ui_lookup_widget(ui_widgets.prefs_dialog, page_name); notebook = GTK_NOTEBOOK(ui_lookup_widget(ui_widgets.prefs_dialog, notebook_name)); if (notebook != NULL && widget != NULL) gtk_notebook_set_current_page(notebook, gtk_notebook_page_num(notebook, widget)); } static void on_customize_toolbar1_activate(GtkMenuItem *menuitem, gpointer user_data) { prefs_show_dialog(); /* select the Interface page */ show_notebook_page("notebook2", "notebook6"); /* select the Toolbar subpage */ show_notebook_page("notebook6", "vbox15"); } static void on_button_customize_toolbar_clicked(GtkButton *button, gpointer user_data) { toolbar_configure(GTK_WINDOW(ui_widgets.prefs_dialog)); } static void on_cut_current_lines1_activate(GtkMenuItem *menuitem, gpointer user_data) { keybindings_send_command(GEANY_KEY_GROUP_CLIPBOARD, GEANY_KEYS_CLIPBOARD_CUTLINE); } static void on_copy_current_lines1_activate(GtkMenuItem *menuitem, gpointer user_data) { keybindings_send_command(GEANY_KEY_GROUP_CLIPBOARD, GEANY_KEYS_CLIPBOARD_COPYLINE); } static void on_delete_current_lines1_activate(GtkMenuItem *menuitem, gpointer user_data) { keybindings_send_command(GEANY_KEY_GROUP_EDITOR, GEANY_KEYS_EDITOR_DELETELINE); } static void on_duplicate_line_or_selection1_activate(GtkMenuItem *menuitem, gpointer user_data) { keybindings_send_command(GEANY_KEY_GROUP_EDITOR, GEANY_KEYS_EDITOR_DUPLICATELINE); } static void on_select_current_lines1_activate(GtkMenuItem *menuitem, gpointer user_data) { keybindings_send_command(GEANY_KEY_GROUP_SELECT, GEANY_KEYS_SELECT_LINE); } static void on_select_current_paragraph1_activate(GtkMenuItem *menuitem, gpointer user_data) { keybindings_send_command(GEANY_KEY_GROUP_SELECT, GEANY_KEYS_SELECT_PARAGRAPH); } static void on_insert_alternative_white_space1_activate(GtkMenuItem *menuitem, gpointer user_data) { keybindings_send_command(GEANY_KEY_GROUP_INSERT, GEANY_KEYS_INSERT_ALTWHITESPACE); } static void on_go_to_next_marker1_activate(GtkMenuItem *menuitem, gpointer user_data) { keybindings_send_command(GEANY_KEY_GROUP_GOTO, GEANY_KEYS_GOTO_NEXTMARKER); } static void on_go_to_previous_marker1_activate(GtkMenuItem *menuitem, gpointer user_data) { keybindings_send_command(GEANY_KEY_GROUP_GOTO, GEANY_KEYS_GOTO_PREVIOUSMARKER); } static void on_join_lines1_activate(GtkMenuItem *menuitem, gpointer user_data) { keybindings_send_command(GEANY_KEY_GROUP_FORMAT, GEANY_KEYS_FORMAT_JOINLINES); } static void on_reflow_lines_block1_activate(GtkMenuItem *menuitem, gpointer user_data) { keybindings_send_command(GEANY_KEY_GROUP_FORMAT, GEANY_KEYS_FORMAT_REFLOWPARAGRAPH); } static void on_move_lines_up1_activate(GtkMenuItem *menuitem, gpointer user_data) { keybindings_send_command(GEANY_KEY_GROUP_EDITOR, GEANY_KEYS_EDITOR_MOVELINEUP); } static void on_move_lines_down1_activate(GtkMenuItem *menuitem, gpointer user_data) { keybindings_send_command(GEANY_KEY_GROUP_EDITOR, GEANY_KEYS_EDITOR_MOVELINEDOWN); } static void on_smart_line_indent1_activate(GtkMenuItem *menuitem, gpointer user_data) { keybindings_send_command(GEANY_KEY_GROUP_FORMAT, GEANY_KEYS_FORMAT_AUTOINDENT); } void on_plugin_preferences1_activate(GtkMenuItem *menuitem, gpointer user_data) { #ifdef HAVE_PLUGINS plugin_show_configure(NULL); #endif } static void on_indent_width_activate(GtkMenuItem *menuitem, gpointer user_data) { GeanyDocument *doc; gchar *label; gint width; if (ignore_callback) return; label = ui_menu_item_get_text(menuitem); width = atoi(label); g_free(label); doc = document_get_current(); if (doc != NULL && width > 0) editor_set_indent_width(doc->editor, width); } static void on_reset_indentation1_activate(GtkMenuItem *menuitem, gpointer user_data) { guint i; foreach_document(i) document_apply_indent_settings(documents[i]); ui_update_statusbar(NULL, -1); ui_document_show_hide(NULL); } static void on_mark_all1_activate(GtkMenuItem *menuitem, gpointer user_data) { keybindings_send_command(GEANY_KEY_GROUP_SEARCH, GEANY_KEYS_SEARCH_MARKALL); } static void on_detect_type_from_file_activate(GtkMenuItem *menuitem, gpointer user_data) { GeanyDocument *doc = document_get_current(); GeanyIndentType type; if (doc != NULL && document_detect_indent_type(doc, &type)) { editor_set_indent_type(doc->editor, type); ui_document_show_hide(doc); ui_update_statusbar(doc, -1); } } static void on_show_symbol_list_toggled(GtkToggleButton *button, gpointer user_data) { GtkWidget *widget = ui_lookup_widget(ui_widgets.prefs_dialog, "box_show_symbol_list_children"); gtk_widget_set_sensitive(widget, gtk_toggle_button_get_active(button)); } static void on_detect_width_from_file_activate(GtkMenuItem *menuitem, gpointer user_data) { GeanyDocument *doc = document_get_current(); gint width; if (doc != NULL && document_detect_indent_width(doc, &width)) { editor_set_indent_width(doc->editor, width); ui_document_show_hide(doc); } } static void builder_connect_func(GtkBuilder *builder, GObject *object, const gchar *signal_name, const gchar *handler_name, GObject *connect_obj, GConnectFlags flags, gpointer user_data) { GHashTable *hash = user_data; GCallback callback; callback = g_hash_table_lookup(hash, handler_name); g_return_if_fail(callback); if (connect_obj == NULL) g_signal_connect_data(object, signal_name, callback, NULL, NULL, flags); else g_signal_connect_object(object, signal_name, callback, connect_obj, flags); } void callbacks_connect(GtkBuilder *builder) { GHashTable *hash; g_return_if_fail(GTK_IS_BUILDER(builder)); hash = g_hash_table_new(g_str_hash, g_str_equal); #define ITEM(n) g_hash_table_insert(hash, (gpointer) #n, G_CALLBACK(n)); # include "signallist.i" #undef ITEM gtk_builder_connect_signals_full(builder, builder_connect_func, hash); g_hash_table_destroy(hash); } geany-2.0/src/Makefile.am0000644000175000017500000001105214514252267012231 00000000000000## Process this file with automake to produce Makefile.in SUBDIRS = tagmanager EXTRA_DIST = \ gb.c \ plugindata.h \ documentprivate.h \ encodingsprivate.h \ filetypesprivate.h \ keybindingsprivate.h \ pluginprivate.h \ projectprivate.h AM_CPPFLAGS = \ -I$(top_srcdir) \ -I$(top_srcdir)/scintilla/include \ -I$(top_srcdir)/scintilla/lexilla/include \ -I$(srcdir)/tagmanager \ -DGTK \ -DGEANY_PRIVATE \ -DG_LOG_DOMAIN=\""Geany"\" \ @GTK_CFLAGS@ \ $(MAC_INTEGRATION_CFLAGS) bin_PROGRAMS = geany lib_LTLIBRARIES = libgeany.la geany_SOURCES = main.c geany_LDADD = libgeany.la $(GTK_LIBS) $(INTLLIBS) geany_LDFLAGS = if ENABLE_BINRELOC geany_LDFLAGS += -Wl,-rpath='$$ORIGIN/../lib' endif geany_includedir = $(includedir)/geany geany_include_HEADERS = \ app.h \ build.h \ dialogs.h \ document.h \ editor.h \ encodings.h \ filetypes.h \ geany.h \ gtkcompat.h \ highlighting.h \ keybindings.h \ main.h \ msgwindow.h \ navqueue.h \ plugindata.h \ pluginutils.h \ prefs.h \ project.h \ sciwrappers.h \ search.h \ spawn.h \ stash.h \ support.h \ symbols.h \ templates.h \ toolbar.h \ ui_utils.h \ utils.h libgeany_la_SOURCES = \ about.c about.h \ app.h \ build.c build.h \ callbacks.c callbacks.h \ dialogs.c dialogs.h \ document.c document.h \ editor.c editor.h \ encodings.c encodings.h \ filetypes.c filetypes.h \ geanyentryaction.c geanyentryaction.h \ geanymenubuttonaction.c geanymenubuttonaction.h \ geanyobject.c geanyobject.h \ geanywraplabel.c geanywraplabel.h \ gtkcompat.h \ highlighting.c highlighting.h \ highlightingmappings.h \ keybindings.c keybindings.h \ keyfile.c keyfile.h \ log.c log.h \ libmain.c main.h geany.h \ msgwindow.c msgwindow.h \ navqueue.c navqueue.h \ notebook.c notebook.h \ plugins.c plugins.h \ pluginutils.c pluginutils.h \ prefs.c prefs.h \ printing.c printing.h \ project.c project.h \ sciwrappers.c sciwrappers.h \ search.c search.h \ socket.c socket.h \ spawn.c spawn.h \ stash.c stash.h \ support.h \ symbols.c symbols.h \ templates.c templates.h \ toolbar.c toolbar.h \ tools.c tools.h \ sidebar.c sidebar.h \ ui_utils.c ui_utils.h \ utils.c utils.h if ENABLE_BINRELOC libgeany_la_SOURCES += prefix.c prefix.h endif if ENABLE_MAC_INTEGRATION libgeany_la_SOURCES += osx.c osx.h endif libgeany_la_CFLAGS = $(AM_CPPFLAGS) @LIBGEANY_CFLAGS@ libgeany_la_LDFLAGS = @LIBGEANY_LDFLAGS@ libgeany_la_LIBADD = \ $(top_builddir)/scintilla/liblexilla.la \ $(top_builddir)/scintilla/libscintilla.la \ $(builddir)/tagmanager/libtagmanager.la \ @GTK_LIBS@ \ $(MAC_INTEGRATION_LIBS) \ $(INTLLIBS) # tell automake we have a C++ file so it uses the C++ linker we need for Scintilla nodist_EXTRA_libgeany_la_SOURCES = dummy1.cxx nodist_EXTRA_geany_SOURCES = dummy2.cxx CLEANFILES = if MINGW # build Geany for Windows (possibly on non-Windows systems -- cross-compile) AM_CPPFLAGS += \ -DGEANY_DATADIR=\"data\" \ -DGEANY_DOCDIR=\"\" \ -DGEANY_LIBDIR=\"\" \ -DGEANY_LIBEXECDIR=\"\" \ -DGEANY_LOCALEDIR=\"\" \ -DGEANY_PREFIX=\"\" geany_LDADD += geany_private.res WINDRES = $(host_alias)-windres geany_private.res: $(top_srcdir)/geany_private.rc $(WINDRES) -i $(top_srcdir)/geany_private.rc --input-format=rc -o $@ -O coff libgeany_la_SOURCES += win32.c win32.h libgeany_la_LIBADD += -lole32 -lwsock32 -lcomdlg32 libgeany_la_LDFLAGS += -mwindows -mms-bitfields -no-undefined geany_LDFLAGS += -mwindows -mms-bitfields CLEANFILES += geany_private.res else # build Geany for all other platforms AM_CPPFLAGS += \ -DGEANY_DATADIR=\""$(datadir)"\" \ -DGEANY_DOCDIR=\""$(docdir)"\" \ -DGEANY_LIBDIR=\""$(libdir)"\" \ -DGEANY_LIBEXECDIR=\""$(libexecdir)"\" \ -DGEANY_LOCALEDIR=\""$(localedir)"\" \ -DGEANY_PREFIX=\""$(prefix)"\" libgeany_la_SOURCES += vte.c vte.h endif callbacks.c: signallist.i glade_file=$(top_srcdir)/data/geany.glade signallist.i: $(glade_file) Makefile $(AM_V_GEN)$(top_srcdir)/scripts/gen-signallist.sh $(glade_file) $@ CLEANFILES += signallist.i # install the run script if MINGW dist_pkglibexec_SCRIPTS = geany-run-helper.bat endif # Ubuntu ld has a bug so that libtool sees /usr/local/lib as a system path so # doesn't add RPATH, but ld requires explicit ldconfig there, unlike when # installing in /usr/lib. So, workaround this by calling it explicitly when # installing in /usr/local/lib and libgeany is not found by the linker. fix-ubuntu-libdir: if test "$(DESTDIR)$(libdir)" = /usr/local/lib && \ LANG=C ldd "$(DESTDIR)$(bindir)/geany" | grep -q 'libgeany.*not found' \ ; then \ ldconfig "$(DESTDIR)$(libdir)"; \ fi install-exec-hook: fix-ubuntu-libdir geany-2.0/src/toolbar.h0000644000175000017500000000352114514252267012012 00000000000000/* * toolbar.h - this file is part of Geany, a fast and lightweight IDE * * Copyright 2009 The Geany contributors * * This program 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; either version 2 of the License, or * (at your option) any later version. * * This program 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef GEANY_TOOLBAR_H #define GEANY_TOOLBAR_H 1 #include "gtkcompat.h" G_BEGIN_DECLS /** Toolbar settings. */ typedef struct GeanyToolbarPrefs { gboolean visible; GtkIconSize icon_size; GtkToolbarStyle icon_style; /**< Icon style. */ gboolean use_gtk_default_style; gboolean use_gtk_default_icon; gboolean append_to_menu; } GeanyToolbarPrefs; #ifdef GEANY_PRIVATE extern GeanyToolbarPrefs toolbar_prefs; GtkWidget *toolbar_get_widget_child_by_name(const gchar *name); GtkWidget *toolbar_get_widget_by_name(const gchar *name); GtkAction *toolbar_get_action_by_name(const gchar *name); gint toolbar_get_insert_position(void); void toolbar_update_ui(void); void toolbar_apply_settings(void); void toolbar_show_hide(void); void toolbar_item_ref(GtkToolItem *item); GtkWidget *toolbar_init(void); void toolbar_finalize(void); void toolbar_configure(GtkWindow *parent); #endif /* GEANY_PRIVATE */ G_END_DECLS #endif /* GEANY_TOOLBAR_H */ geany-2.0/src/project.c0000644000175000017500000012261114514252267012013 00000000000000/* * project.c - this file is part of Geany, a fast and lightweight IDE * * Copyright 2007 The Geany contributors * * This program 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; either version 2 of the License, or * (at your option) any later version. * * This program 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /** @file project.h * Project Management. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include "project.h" #include "app.h" #include "build.h" #include "dialogs.h" #include "document.h" #include "editor.h" #include "filetypesprivate.h" #include "geanyobject.h" #include "keyfile.h" #include "main.h" #include "projectprivate.h" #include "sidebar.h" #include "stash.h" #include "support.h" #include "ui_utils.h" #include "utils.h" #include #include #include ProjectPrefs project_prefs = { NULL, FALSE }; static GeanyProjectPrivate priv; static GeanyIndentPrefs indentation; static GSList *stash_groups = NULL; static struct { gchar *project_file_path; /* in UTF-8 */ } local_prefs = { NULL }; /* simple struct to keep references to the elements of the properties dialog */ typedef struct _PropertyDialogElements { GtkWidget *dialog; GtkWidget *notebook; GtkWidget *name; GtkWidget *description; GtkWidget *file_name; GtkWidget *base_path; GtkWidget *patterns; BuildTableData build_properties; gint build_page_num; gboolean entries_modified; } PropertyDialogElements; static gboolean update_config(const PropertyDialogElements *e, gboolean new_project); static void on_file_save_button_clicked(GtkButton *button, PropertyDialogElements *e); static gboolean load_config(const gchar *filename); static gboolean write_config(void); static void update_new_project_dlg(GtkEditable *editable, PropertyDialogElements *e, const gchar *base_p); static void on_name_entry_changed(GtkEditable *editable, PropertyDialogElements *e); static void on_entries_changed(GtkEditable *editable, PropertyDialogElements *e); static void on_radio_long_line_custom_toggled(GtkToggleButton *radio, GtkWidget *spin_long_line); static void run_new_dialog(PropertyDialogElements *e); static void apply_editor_prefs(void); static void init_stash_prefs(void); static void destroy_project(gboolean open_default); #define SHOW_ERR(args) dialogs_show_msgbox(GTK_MESSAGE_ERROR, args) #define SHOW_ERR1(args, more) dialogs_show_msgbox(GTK_MESSAGE_ERROR, args, more) #define MAX_NAME_LEN 50 /* "projects" is part of the default project base path so be careful when translating * please avoid special characters and spaces, look at the source for details or ask Frank */ #define PROJECT_DIR _("projects") // returns whether we have working documents open static gboolean have_session_docs(void) { gint npages = gtk_notebook_get_n_pages(GTK_NOTEBOOK(main_widgets.notebook)); GeanyDocument *doc = document_get_current(); return npages > 1 || (npages == 1 && (doc->file_name || doc->changed)); } static gboolean handle_current_session(void) { if (!app->project) { /* save session in case the dialog is cancelled */ configuration_save_default_session(); /* don't ask if the only doc is an unmodified new doc */ if (have_session_docs()) { if (dialogs_show_question( _("Move the current documents into the new project's session?"))) { // don't reload session on closing project configuration_clear_default_session(); } else { if (!document_close_all()) return FALSE; } } } if (app->project) return project_close(FALSE); return TRUE; } /* TODO: this should be ported to Glade like the project preferences dialog, * then we can get rid of the PropertyDialogElements struct altogether as * widgets pointers can be accessed through ui_lookup_widget(). */ void project_new(gboolean from_folder) { GtkWidget *vbox; GtkWidget *table; GtkWidget *image; GtkWidget *button; GtkWidget *bbox; GtkWidget *label; gchar *tooltip; gchar *base_path = NULL; PropertyDialogElements e = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, FALSE }; if (from_folder) { GeanyDocument *doc = document_get_current(); gchar *start_path; if (doc && doc->file_name) start_path = g_path_get_dirname(doc->file_name); else if (!EMPTY(local_prefs.project_file_path)) start_path = g_strdup(local_prefs.project_file_path); else start_path = utils_get_utf8_from_locale(g_get_home_dir()); base_path = ui_get_project_directory(start_path); g_free(start_path); if (!base_path) return; } e.dialog = gtk_dialog_new_with_buttons(_("New Project"), GTK_WINDOW(main_widgets.window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL); gtk_widget_set_name(e.dialog, "GeanyDialogProject"); button = ui_button_new_with_image(GTK_STOCK_NEW, _("C_reate")); gtk_widget_set_can_default(button, TRUE); gtk_window_set_default(GTK_WINDOW(e.dialog), button); gtk_dialog_add_action_widget(GTK_DIALOG(e.dialog), button, GTK_RESPONSE_OK); vbox = ui_dialog_vbox_new(GTK_DIALOG(e.dialog)); table = gtk_table_new(3, 2, FALSE); gtk_table_set_row_spacings(GTK_TABLE(table), 5); gtk_table_set_col_spacings(GTK_TABLE(table), 10); label = gtk_label_new(_("Name:")); gtk_misc_set_alignment(GTK_MISC(label), 1, 0); e.name = gtk_entry_new(); gtk_entry_set_activates_default(GTK_ENTRY(e.name), TRUE); ui_entry_add_clear_icon(GTK_ENTRY(e.name)); gtk_entry_set_max_length(GTK_ENTRY(e.name), MAX_NAME_LEN); gtk_widget_set_tooltip_text(e.name, _("Project name")); ui_table_add_row(GTK_TABLE(table), 0, label, e.name, NULL); label = gtk_label_new(_("Filename:")); gtk_misc_set_alignment(GTK_MISC(label), 1, 0); e.file_name = gtk_entry_new(); gtk_entry_set_activates_default(GTK_ENTRY(e.file_name), TRUE); ui_entry_add_clear_icon(GTK_ENTRY(e.file_name)); gtk_entry_set_width_chars(GTK_ENTRY(e.file_name), 40); tooltip = g_strdup_printf( _("Path of the file representing the project and storing its settings. " "It should normally have the \"%s\" extension."), "."GEANY_PROJECT_EXT); gtk_widget_set_tooltip_text(e.file_name, tooltip); g_free(tooltip); button = gtk_button_new(); g_signal_connect(button, "clicked", G_CALLBACK(on_file_save_button_clicked), &e); image = gtk_image_new_from_stock(GTK_STOCK_OPEN, GTK_ICON_SIZE_BUTTON); gtk_container_add(GTK_CONTAINER(button), image); bbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6); gtk_box_pack_start(GTK_BOX(bbox), e.file_name, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); ui_table_add_row(GTK_TABLE(table), 1, label, bbox, NULL); label = gtk_label_new(_("Base path:")); gtk_misc_set_alignment(GTK_MISC(label), 1, 0); e.base_path = gtk_entry_new(); gtk_entry_set_activates_default(GTK_ENTRY(e.base_path), TRUE); ui_entry_add_clear_icon(GTK_ENTRY(e.base_path)); gtk_widget_set_tooltip_text(e.base_path, _("Base directory of all files that make up the project. " "This can be a new path, or an existing directory tree. " "You can use paths relative to the project filename.")); bbox = ui_path_box_new(_("Choose Project Base Path"), GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, GTK_ENTRY(e.base_path)); ui_table_add_row(GTK_TABLE(table), 2, label, bbox, NULL); gtk_box_pack_start(GTK_BOX(vbox), table, TRUE, TRUE, 0); if (base_path) { update_new_project_dlg(GTK_EDITABLE(e.name), &e, base_path); g_free(base_path); } else { /* signals */ g_signal_connect(e.name, "changed", G_CALLBACK(on_name_entry_changed), &e); g_signal_connect(e.file_name, "changed", G_CALLBACK(on_entries_changed), &e); g_signal_connect(e.base_path, "changed", G_CALLBACK(on_entries_changed), &e); update_new_project_dlg(GTK_EDITABLE(e.name), &e, NULL); } gtk_widget_show_all(e.dialog); run_new_dialog(&e); gtk_widget_destroy(e.dialog); document_new_file_if_non_open(); ui_focus_current_document(); } static void run_new_dialog(PropertyDialogElements *e) { if (gtk_dialog_run(GTK_DIALOG(e->dialog)) != GTK_RESPONSE_OK || !handle_current_session()) return; do { if (update_config(e, TRUE)) { // app->project is now set if (!write_config()) { SHOW_ERR(_("Project file could not be written")); destroy_project(FALSE); } else { ui_set_statusbar(TRUE, _("Project \"%s\" created."), app->project->name); ui_add_recent_project_file(app->project->file_name); return; } } } while (gtk_dialog_run(GTK_DIALOG(e->dialog)) == GTK_RESPONSE_OK); // any open docs were meant to be moved into the project // rewrite default session because it was cleared if (have_session_docs()) configuration_save_default_session(); else { // reload any documents that were closed configuration_load_default_session(); configuration_open_default_session(); } } gboolean project_load_file_with_session(const gchar *locale_file_name) { if (project_load_file(locale_file_name)) { configuration_open_files(app->project->priv->session_files); app->project->priv->session_files = NULL; document_new_file_if_non_open(); ui_focus_current_document(); return TRUE; } return FALSE; } static void run_open_dialog(GtkDialog *dialog) { while (gtk_dialog_run(dialog) == GTK_RESPONSE_ACCEPT) { gchar *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); if (app->project && !project_close(FALSE)) {} /* try to load the config */ else if (! project_load_file_with_session(filename)) { gchar *utf8_filename = utils_get_utf8_from_locale(filename); SHOW_ERR1(_("Project file \"%s\" could not be loaded."), utf8_filename); gtk_widget_grab_focus(GTK_WIDGET(dialog)); g_free(utf8_filename); g_free(filename); continue; } g_free(filename); break; } } void project_open(void) { const gchar *dir = local_prefs.project_file_path; gchar *locale_path; GtkWidget *dialog; GtkFileFilter *filter; dialog = gtk_file_chooser_dialog_new(_("Open Project"), GTK_WINDOW(main_widgets.window), GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL); gtk_widget_set_name(dialog, "GeanyDialogProject"); /* set default Open, so pressing enter can open multiple files */ gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT); gtk_window_set_destroy_with_parent(GTK_WINDOW(dialog), TRUE); gtk_window_set_skip_taskbar_hint(GTK_WINDOW(dialog), TRUE); gtk_window_set_type_hint(GTK_WINDOW(dialog), GDK_WINDOW_TYPE_HINT_DIALOG); gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(main_widgets.window)); gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), TRUE); /* add FileFilters */ filter = gtk_file_filter_new(); gtk_file_filter_set_name(filter, _("All files")); gtk_file_filter_add_pattern(filter, "*"); gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter); filter = gtk_file_filter_new(); gtk_file_filter_set_name(filter, _("Project files")); gtk_file_filter_add_pattern(filter, "*." GEANY_PROJECT_EXT); gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter); gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(dialog), filter); locale_path = utils_get_locale_from_utf8(dir); if (g_file_test(locale_path, G_FILE_TEST_EXISTS) && g_file_test(locale_path, G_FILE_TEST_IS_DIR)) { gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), locale_path); } g_free(locale_path); gtk_widget_show_all(dialog); run_open_dialog(GTK_DIALOG(dialog)); gtk_widget_destroy(GTK_WIDGET(dialog)); } /* Called when creating, opening, closing and updating projects. */ static void update_ui(void) { if (main_status.quitting) return; ui_set_window_title(NULL); build_menu_update(NULL); // update project name sidebar_openfiles_update_all(); ui_update_recent_project_menu(); } static void remove_foreach_project_filetype(gpointer data, gpointer user_data) { GeanyFiletype *ft = data; if (ft != NULL) { SETPTR(ft->priv->projfilecmds, NULL); SETPTR(ft->priv->projexeccmds, NULL); SETPTR(ft->priv->projerror_regex_string, NULL); ft->priv->project_list_entry = -1; } } /* open_default will make function reload default session files on close */ gboolean project_close(gboolean open_default) { g_return_val_if_fail(app->project != NULL, FALSE); /* save project session files, etc */ if (!write_config()) g_warning("Project file \"%s\" could not be written", app->project->file_name); /* close all existing tabs first */ if (!document_close_all()) return FALSE; ui_set_statusbar(TRUE, _("Project \"%s\" closed."), app->project->name); destroy_project(open_default); return TRUE; } static void destroy_project(gboolean open_default) { GSList *node; g_return_if_fail(app->project != NULL); g_signal_emit_by_name(geany_object, "project-before-close"); /* remove project filetypes build entries */ if (app->project->priv->build_filetypes_list != NULL) { g_ptr_array_foreach(app->project->priv->build_filetypes_list, remove_foreach_project_filetype, NULL); g_ptr_array_free(app->project->priv->build_filetypes_list, FALSE); } /* remove project non filetype build menu items */ build_remove_menu_item(GEANY_BCS_PROJ, GEANY_GBG_NON_FT, -1); build_remove_menu_item(GEANY_BCS_PROJ, GEANY_GBG_EXEC, -1); g_free(app->project->name); g_free(app->project->description); g_free(app->project->file_name); g_free(app->project->base_path); g_strfreev(app->project->file_patterns); g_free(app->project); app->project = NULL; foreach_slist(node, stash_groups) stash_group_free(node->data); g_slist_free(stash_groups); stash_groups = NULL; apply_editor_prefs(); /* ensure that global settings are restored */ /* after closing all tabs let's open the tabs found in the default config */ if (open_default && cl_options.load_session) { configuration_load_default_session(); configuration_open_default_session(); document_new_file_if_non_open(); ui_focus_current_document(); } g_signal_emit_by_name(geany_object, "project-close"); update_ui(); } /* Shows the file chooser dialog when base path button is clicked * FIXME: this should be connected in Glade but 3.8.1 has a bug * where it won't pass any objects as user data (#588824). */ static void on_project_properties_base_path_button_clicked(GtkWidget *button, GtkWidget *base_path_entry) { GtkWidget *dialog; g_return_if_fail(base_path_entry != NULL); g_return_if_fail(GTK_IS_WIDGET(base_path_entry)); dialog = gtk_file_chooser_dialog_new(_("Choose Project Base Path"), NULL, GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL); if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { gtk_entry_set_text(GTK_ENTRY(base_path_entry), gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog))); } gtk_widget_destroy(dialog); } static void insert_build_page(PropertyDialogElements *e) { GtkWidget *build_table, *label; GeanyDocument *doc = document_get_current(); GeanyFiletype *ft = NULL; if (doc != NULL) ft = doc->file_type; build_table = build_commands_table(doc, GEANY_BCS_PROJ, &(e->build_properties), ft); gtk_container_set_border_width(GTK_CONTAINER(build_table), 6); label = gtk_label_new(_("Build")); e->build_page_num = gtk_notebook_append_page(GTK_NOTEBOOK(e->notebook), build_table, label); } static void create_properties_dialog(PropertyDialogElements *e) { GtkWidget *wid; static guint base_path_button_handler_id = 0; static guint radio_long_line_handler_id = 0; e->dialog = create_project_dialog(); e->notebook = ui_lookup_widget(e->dialog, "project_notebook"); e->file_name = ui_lookup_widget(e->dialog, "label_project_dialog_filename"); e->name = ui_lookup_widget(e->dialog, "entry_project_dialog_name"); e->description = ui_lookup_widget(e->dialog, "textview_project_dialog_description"); e->base_path = ui_lookup_widget(e->dialog, "entry_project_dialog_base_path"); e->patterns = ui_lookup_widget(e->dialog, "entry_project_dialog_file_patterns"); gtk_entry_set_max_length(GTK_ENTRY(e->name), MAX_NAME_LEN); ui_entry_add_clear_icon(GTK_ENTRY(e->name)); ui_entry_add_clear_icon(GTK_ENTRY(e->base_path)); ui_entry_add_clear_icon(GTK_ENTRY(e->patterns)); /* Workaround for bug in Glade 3.8.1, see comment above signal handler */ if (base_path_button_handler_id == 0) { wid = ui_lookup_widget(e->dialog, "button_project_dialog_base_path"); base_path_button_handler_id = g_signal_connect(wid, "clicked", G_CALLBACK(on_project_properties_base_path_button_clicked), e->base_path); } /* Same as above, should be in Glade but can't due to bug in 3.8.1 */ if (radio_long_line_handler_id == 0) { wid = ui_lookup_widget(e->dialog, "radio_long_line_custom_project"); radio_long_line_handler_id = g_signal_connect(wid, "toggled", G_CALLBACK(on_radio_long_line_custom_toggled), ui_lookup_widget(e->dialog, "spin_long_line_project")); } } static void show_project_properties(gboolean show_build) { GeanyProject *p = app->project; GtkWidget *widget = NULL; GtkWidget *radio_long_line_custom; static PropertyDialogElements e; GSList *node; gchar *entry_text; GtkTextBuffer *buffer; g_return_if_fail(app->project != NULL); if (e.dialog == NULL) create_properties_dialog(&e); insert_build_page(&e); foreach_slist(node, stash_groups) stash_group_display(node->data, e.dialog); /* fill the elements with the appropriate data */ gtk_entry_set_text(GTK_ENTRY(e.name), p->name); gtk_label_set_text(GTK_LABEL(e.file_name), p->file_name); gtk_entry_set_text(GTK_ENTRY(e.base_path), p->base_path); radio_long_line_custom = ui_lookup_widget(e.dialog, "radio_long_line_custom_project"); switch (p->priv->long_line_behaviour) { case 0: widget = ui_lookup_widget(e.dialog, "radio_long_line_disabled_project"); break; case 1: widget = ui_lookup_widget(e.dialog, "radio_long_line_default_project"); break; case 2: widget = radio_long_line_custom; break; } gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), TRUE); widget = ui_lookup_widget(e.dialog, "spin_long_line_project"); gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget), (gdouble)p->priv->long_line_column); on_radio_long_line_custom_toggled(GTK_TOGGLE_BUTTON(radio_long_line_custom), widget); /* set text */ buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(e.description)); gtk_text_buffer_set_text(buffer, p->description ? p->description : "", -1); /* set the file patterns */ entry_text = p->file_patterns ? g_strjoinv(" ", p->file_patterns) : g_strdup(""); gtk_entry_set_text(GTK_ENTRY(e.patterns), entry_text); g_free(entry_text); g_signal_emit_by_name(geany_object, "project-dialog-open", e.notebook); gtk_widget_show_all(e.dialog); /* note: notebook page must be shown before setting current page */ if (show_build) gtk_notebook_set_current_page(GTK_NOTEBOOK(e.notebook), e.build_page_num); else gtk_notebook_set_current_page(GTK_NOTEBOOK(e.notebook), 0); while (gtk_dialog_run(GTK_DIALOG(e.dialog)) == GTK_RESPONSE_OK) { if (update_config(&e, FALSE)) { g_signal_emit_by_name(geany_object, "project-dialog-confirmed", e.notebook); if (!write_config()) SHOW_ERR(_("Project file could not be written")); else { ui_set_statusbar(TRUE, _("Project \"%s\" saved."), app->project->name); break; } } } build_free_fields(e.build_properties); g_signal_emit_by_name(geany_object, "project-dialog-close", e.notebook); gtk_notebook_remove_page(GTK_NOTEBOOK(e.notebook), e.build_page_num); gtk_widget_hide(e.dialog); } void project_properties(void) { show_project_properties(FALSE); } void project_build_properties(void) { show_project_properties(TRUE); } /* checks whether there is an already open project and asks the user if he wants to close it or * abort the current action. Returns FALSE when the current action(the caller) should be cancelled * and TRUE if we can go ahead */ gboolean project_ask_close(void) { if (app->project != NULL) { if (!interface_prefs.warn_on_project_close || dialogs_show_question_full(NULL, GTK_STOCK_CLOSE, GTK_STOCK_CANCEL, _("Do you want to close it before proceeding?"), _("The '%s' project is open."), app->project->name)) { return project_close(FALSE); } else return FALSE; } else return TRUE; } static GeanyProject *create_project(void) { GeanyProject *project = g_new0(GeanyProject, 1); memset(&priv, 0, sizeof priv); priv.indentation = &indentation; project->priv = &priv; init_stash_prefs(); project->file_patterns = NULL; project->priv->long_line_behaviour = 1 /* use global settings */; project->priv->long_line_column = editor_prefs.long_line_column; app->project = project; return project; } /* Verifies data for New & Properties dialogs. * Creates app->project if NULL. * Returns: FALSE if the user needs to change any data. */ static gboolean update_config(const PropertyDialogElements *e, gboolean new_project) { const gchar *name, *file_name, *base_path; gchar *locale_filename; gsize name_len; gint err_code = 0; GeanyProject *p; g_return_val_if_fail(e != NULL, TRUE); name = gtk_entry_get_text(GTK_ENTRY(e->name)); name_len = strlen(name); if (name_len == 0) { SHOW_ERR(_("The specified project name is too short.")); gtk_widget_grab_focus(e->name); return FALSE; } else if (name_len > MAX_NAME_LEN) { SHOW_ERR1(_("The specified project name is too long (max. %d characters)."), MAX_NAME_LEN); gtk_widget_grab_focus(e->name); return FALSE; } if (new_project) file_name = gtk_entry_get_text(GTK_ENTRY(e->file_name)); else file_name = gtk_label_get_text(GTK_LABEL(e->file_name)); if (G_UNLIKELY(EMPTY(file_name))) { SHOW_ERR(_("You have specified an invalid project filename.")); gtk_widget_grab_focus(e->file_name); return FALSE; } locale_filename = utils_get_locale_from_utf8(file_name); base_path = gtk_entry_get_text(GTK_ENTRY(e->base_path)); if (!EMPTY(base_path)) { /* check whether the given directory actually exists */ gchar *locale_path = utils_get_locale_from_utf8(base_path); if (! g_path_is_absolute(locale_path)) { /* relative base path, so add base dir of project file name */ gchar *dir = g_path_get_dirname(locale_filename); SETPTR(locale_path, g_build_filename(dir, locale_path, NULL)); g_free(dir); } if (! g_file_test(locale_path, G_FILE_TEST_IS_DIR)) { gboolean create_dir; create_dir = dialogs_show_question_full(NULL, GTK_STOCK_OK, GTK_STOCK_CANCEL, _("Create the project's base path directory?"), _("The path \"%s\" does not exist."), base_path); if (create_dir) err_code = utils_mkdir(locale_path, TRUE); if (! create_dir || err_code != 0) { if (err_code != 0) SHOW_ERR1(_("Project base directory could not be created (%s)."), g_strerror(err_code)); gtk_widget_grab_focus(e->base_path); utils_free_pointers(2, locale_path, locale_filename, NULL); return FALSE; } } g_free(locale_path); } /* finally test whether the given project file can be written */ if ((err_code = utils_is_file_writable(locale_filename)) != 0 || (err_code = g_file_test(locale_filename, G_FILE_TEST_IS_DIR) ? EISDIR : 0) != 0) { SHOW_ERR1(_("Project file could not be written (%s)."), g_strerror(err_code)); gtk_widget_grab_focus(e->file_name); g_free(locale_filename); return FALSE; } else if (new_project && g_file_test(locale_filename, G_FILE_TEST_EXISTS) && ! dialogs_show_question_full(NULL, _("_Replace"), GTK_STOCK_CANCEL, NULL, _("The file '%s' already exists. Do you want to overwrite it?"), file_name)) { gtk_widget_grab_focus(e->file_name); g_free(locale_filename); return FALSE; } g_free(locale_filename); if (app->project == NULL) { create_project(); new_project = TRUE; } p = app->project; SETPTR(p->name, g_strdup(name)); SETPTR(p->file_name, g_strdup(file_name)); /* use "." if base_path is empty */ SETPTR(p->base_path, g_strdup(!EMPTY(base_path) ? base_path : "./")); if (! new_project) /* save properties specific fields */ { GtkTextIter start, end; GtkTextBuffer *buffer; GeanyDocument *doc = document_get_current(); GeanyBuildCommand *oldvalue; GeanyFiletype *ft = doc ? doc->file_type : NULL; GtkWidget *widget; gchar *tmp; GString *str; GSList *node; /* get and set the project description */ buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(e->description)); gtk_text_buffer_get_start_iter(buffer, &start); gtk_text_buffer_get_end_iter(buffer, &end); SETPTR(p->description, gtk_text_buffer_get_text(buffer, &start, &end, FALSE)); foreach_slist(node, stash_groups) stash_group_update(node->data, e->dialog); /* read the project build menu */ oldvalue = ft ? ft->priv->projfilecmds : NULL; build_read_project(ft, e->build_properties); if (ft != NULL && ft->priv->projfilecmds != oldvalue && ft->priv->project_list_entry < 0) { if (p->priv->build_filetypes_list == NULL) p->priv->build_filetypes_list = g_ptr_array_new(); ft->priv->project_list_entry = p->priv->build_filetypes_list->len; g_ptr_array_add(p->priv->build_filetypes_list, ft); } build_menu_update(doc); widget = ui_lookup_widget(e->dialog, "radio_long_line_disabled_project"); if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) p->priv->long_line_behaviour = 0; else { widget = ui_lookup_widget(e->dialog, "radio_long_line_default_project"); if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) p->priv->long_line_behaviour = 1; else /* "Custom" radio button must be checked */ p->priv->long_line_behaviour = 2; } widget = ui_lookup_widget(e->dialog, "spin_long_line_project"); p->priv->long_line_column = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget)); apply_editor_prefs(); /* get and set the project file patterns */ tmp = g_strdup(gtk_entry_get_text(GTK_ENTRY(e->patterns))); g_strfreev(p->file_patterns); g_strstrip(tmp); str = g_string_new(tmp); do {} while (utils_string_replace_all(str, " ", " ")); p->file_patterns = g_strsplit(str->str, " ", -1); g_string_free(str, TRUE); g_free(tmp); } update_ui(); return TRUE; } static void run_dialog(GtkWidget *dialog, GtkWidget *entry) { /* set filename in the file chooser dialog */ const gchar *utf8_filename = gtk_entry_get_text(GTK_ENTRY(entry)); gchar *locale_filename = utils_get_locale_from_utf8(utf8_filename); if (g_path_is_absolute(locale_filename)) { if (g_file_test(locale_filename, G_FILE_TEST_EXISTS)) { /* if the current filename is a directory, we must use * gtk_file_chooser_set_current_folder(which expects a locale filename) otherwise * we end up in the parent directory */ if (g_file_test(locale_filename, G_FILE_TEST_IS_DIR)) gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), locale_filename); else gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), utf8_filename); } else /* if the file doesn't yet exist, use at least the current directory */ { gchar *locale_dir = g_path_get_dirname(locale_filename); gchar *name = g_path_get_basename(utf8_filename); if (g_file_test(locale_dir, G_FILE_TEST_EXISTS)) gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), locale_dir); gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), name); g_free(name); g_free(locale_dir); } } else if (gtk_file_chooser_get_action(GTK_FILE_CHOOSER(dialog)) != GTK_FILE_CHOOSER_ACTION_OPEN) { gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), utf8_filename); } g_free(locale_filename); /* run it */ if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { gchar *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); gchar *tmp_utf8_filename = utils_get_utf8_from_locale(filename); gtk_entry_set_text(GTK_ENTRY(entry), tmp_utf8_filename); g_free(tmp_utf8_filename); g_free(filename); } gtk_widget_destroy(dialog); } static void on_file_save_button_clicked(GtkButton *button, PropertyDialogElements *e) { GtkWidget *dialog; /* initialise the dialog */ dialog = gtk_file_chooser_dialog_new(_("Choose Project Filename"), NULL, GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL); gtk_widget_set_name(dialog, "GeanyDialogProject"); gtk_window_set_destroy_with_parent(GTK_WINDOW(dialog), TRUE); gtk_window_set_skip_taskbar_hint(GTK_WINDOW(dialog), TRUE); gtk_window_set_type_hint(GTK_WINDOW(dialog), GDK_WINDOW_TYPE_HINT_DIALOG); gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT); run_dialog(dialog, e->file_name); } /* sets the New Project dialog entries according to the base path or project name */ static void update_new_project_dlg(GtkEditable *editable, PropertyDialogElements *e, const gchar *base_p) { gchar *base_path; gchar *file_name; gchar *project_dir = NULL; if (e->entries_modified) return; if (!EMPTY(local_prefs.project_file_path)) project_dir = g_strdup(local_prefs.project_file_path); else { GeanyDocument *doc = document_get_current(); if (doc && doc->file_name) project_dir = g_path_get_dirname(doc->file_name); else project_dir = utils_get_utf8_from_locale(g_get_home_dir()); } if (!EMPTY(base_p)) { gchar *name = g_path_get_basename(base_p); base_path = g_strdup(base_p); gtk_entry_set_text(GTK_ENTRY(e->name), name); if (project_prefs.project_file_in_basedir) file_name = g_strconcat(base_path, G_DIR_SEPARATOR_S, name, "." GEANY_PROJECT_EXT, NULL); else file_name = g_strconcat(project_dir, G_DIR_SEPARATOR_S, name, "." GEANY_PROJECT_EXT, NULL); g_free(name); } else { gchar *name = gtk_editable_get_chars(editable, 0, -1); if (!EMPTY(name)) { base_path = g_strconcat(project_dir, G_DIR_SEPARATOR_S, name, G_DIR_SEPARATOR_S, NULL); if (project_prefs.project_file_in_basedir) file_name = g_strconcat(project_dir, G_DIR_SEPARATOR_S, name, G_DIR_SEPARATOR_S, name, "." GEANY_PROJECT_EXT, NULL); else file_name = g_strconcat(project_dir, G_DIR_SEPARATOR_S, name, "." GEANY_PROJECT_EXT, NULL); } else { base_path = g_strconcat(project_dir, G_DIR_SEPARATOR_S, NULL); file_name = g_strconcat(project_dir, G_DIR_SEPARATOR_S, NULL); } g_free(name); } gtk_entry_set_text(GTK_ENTRY(e->base_path), base_path); gtk_entry_set_text(GTK_ENTRY(e->file_name), file_name); e->entries_modified = FALSE; g_free(base_path); g_free(file_name); g_free(project_dir); } static void on_name_entry_changed(GtkEditable *editable, PropertyDialogElements *e) { update_new_project_dlg(editable, e, NULL); } static void on_entries_changed(GtkEditable *editable, PropertyDialogElements *e) { e->entries_modified = TRUE; } static void on_radio_long_line_custom_toggled(GtkToggleButton *radio, GtkWidget *spin_long_line) { gtk_widget_set_sensitive(spin_long_line, gtk_toggle_button_get_active(radio)); } gboolean project_load_file(const gchar *locale_file_name) { g_return_val_if_fail(locale_file_name != NULL, FALSE); if (load_config(locale_file_name)) { gchar *utf8_filename = utils_get_utf8_from_locale(locale_file_name); ui_set_statusbar(TRUE, _("Project \"%s\" opened."), app->project->name); ui_add_recent_project_file(utf8_filename); g_free(utf8_filename); return TRUE; } else { gchar *utf8_filename = utils_get_utf8_from_locale(locale_file_name); ui_set_statusbar(TRUE, _("Project file \"%s\" could not be loaded."), utf8_filename); g_free(utf8_filename); } return FALSE; } /* Reads the given filename and creates a new project with the data found in the file. * At this point there should not be an already opened project in Geany otherwise it will just * return. * The filename is expected in the locale encoding. */ static gboolean load_config(const gchar *filename) { GKeyFile *config; GeanyProject *p; GSList *node; /* there should not be an open project */ g_return_val_if_fail(app->project == NULL && filename != NULL, FALSE); config = g_key_file_new(); if (! g_key_file_load_from_file(config, filename, G_KEY_FILE_NONE, NULL)) { g_key_file_free(config); return FALSE; } p = create_project(); foreach_slist(node, stash_groups) stash_group_load_from_key_file(node->data, config); p->name = utils_get_setting_string(config, "project", "name", GEANY_STRING_UNTITLED); p->description = utils_get_setting_string(config, "project", "description", ""); p->file_name = utils_get_utf8_from_locale(filename); p->base_path = utils_get_setting_string(config, "project", "base_path", ""); p->file_patterns = g_key_file_get_string_list(config, "project", "file_patterns", NULL, NULL); p->priv->long_line_behaviour = utils_get_setting_integer(config, "long line marker", "long_line_behaviour", 1 /* follow global */); p->priv->long_line_column = utils_get_setting_integer(config, "long line marker", "long_line_column", editor_prefs.long_line_column); apply_editor_prefs(); build_load_menu(config, GEANY_BCS_PROJ, (gpointer)p); /* save current (non-project) session (it could have been changed since program startup) */ if (!main_status.opening_session_files) { configuration_save_default_session(); /* now close all open files */ document_close_all(); } /* read session files so they can be opened with configuration_open_files() */ p->priv->session_files = configuration_load_session_files(config); g_signal_emit_by_name(geany_object, "project-open", config); g_key_file_free(config); update_ui(); return TRUE; } static void apply_editor_prefs(void) { guint i; foreach_document(i) editor_apply_update_prefs(documents[i]->editor); } /* Write the project settings as well as the project session files into its configuration files. * Returns: TRUE if project file was written successfully. */ static gboolean write_config(void) { GeanyProject *p; GKeyFile *config; gchar *filename; gchar *data; gboolean ret = FALSE; GSList *node; g_return_val_if_fail(app->project != NULL, FALSE); p = app->project; config = g_key_file_new(); /* try to load an existing config to keep manually added comments */ filename = utils_get_locale_from_utf8(p->file_name); g_key_file_load_from_file(config, filename, G_KEY_FILE_NONE, NULL); foreach_slist(node, stash_groups) stash_group_save_to_key_file(node->data, config); g_key_file_set_string(config, "project", "name", p->name); g_key_file_set_string(config, "project", "base_path", p->base_path); if (p->description) g_key_file_set_string(config, "project", "description", p->description); if (p->file_patterns) g_key_file_set_string_list(config, "project", "file_patterns", (const gchar**) p->file_patterns, g_strv_length(p->file_patterns)); // editor settings g_key_file_set_integer(config, "long line marker", "long_line_behaviour", p->priv->long_line_behaviour); g_key_file_set_integer(config, "long line marker", "long_line_column", p->priv->long_line_column); /* store the session files into the project too */ configuration_save_session_files(config); build_save_menu(config, (gpointer)p, GEANY_BCS_PROJ); g_signal_emit_by_name(geany_object, "project-save", config); /* write the file */ data = g_key_file_to_data(config, NULL, NULL); ret = (utils_write_file(filename, data) == 0); g_free(data); g_free(filename); g_key_file_free(config); return ret; } /** Forces the project file rewrite and emission of the project-save signal. Plugins * can use this function to save additional project data outside the project dialog. * * @since 1.25 */ GEANY_API_SYMBOL void project_write_config(void) { if (!write_config()) SHOW_ERR(_("Project file could not be written")); } /* Constructs the project's base path which is used for "Make all" and "Execute". * The result is an absolute string in UTF-8 encoding which is either the same as * base path if it is absolute or it is built out of project file name's dir and base_path. * If there is no project or project's base_path is invalid, NULL will be returned. * The returned string should be freed when no longer needed. */ gchar *project_get_base_path(void) { GeanyProject *project = app->project; if (project && !EMPTY(project->base_path)) { if (g_path_is_absolute(project->base_path)) return g_strdup(project->base_path); else { /* build base_path out of project file name's dir and base_path */ gchar *path; gchar *dir = g_path_get_dirname(project->file_name); if (utils_str_equal(project->base_path, "./")) return dir; path = g_build_filename(dir, project->base_path, NULL); g_free(dir); return path; } } return NULL; } /* This is to save project-related global settings, NOT project file settings. */ void project_save_prefs(GKeyFile *config) { GeanyProject *project = app->project; if (cl_options.load_session) { const gchar *utf8_filename = (project == NULL) ? "" : project->file_name; g_key_file_set_string(config, "project", "session_file", utf8_filename); } g_key_file_set_string(config, "project", "project_file_path", FALLBACK(local_prefs.project_file_path, "")); } void project_load_prefs(GKeyFile *config) { if (cl_options.load_session) { g_return_if_fail(project_prefs.session_file == NULL); project_prefs.session_file = utils_get_setting_string(config, "project", "session_file", ""); } local_prefs.project_file_path = utils_get_setting_string(config, "project", "project_file_path", NULL); if (local_prefs.project_file_path == NULL) { local_prefs.project_file_path = g_build_filename(g_get_home_dir(), PROJECT_DIR, NULL); } } /* Initialize project-related preferences in the Preferences dialog. */ void project_setup_prefs(void) { GtkWidget *path_entry = ui_lookup_widget(ui_widgets.prefs_dialog, "project_file_path_entry"); GtkWidget *path_btn = ui_lookup_widget(ui_widgets.prefs_dialog, "project_file_path_button"); static gboolean callback_setup = FALSE; g_return_if_fail(local_prefs.project_file_path != NULL); gtk_entry_set_text(GTK_ENTRY(path_entry), local_prefs.project_file_path); if (! callback_setup) { /* connect the callback only once */ callback_setup = TRUE; ui_setup_open_button_callback(path_btn, NULL, GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, GTK_ENTRY(path_entry)); } } /* Update project-related preferences after using the Preferences dialog. */ void project_apply_prefs(void) { GtkWidget *path_entry = ui_lookup_widget(ui_widgets.prefs_dialog, "project_file_path_entry"); const gchar *str; str = gtk_entry_get_text(GTK_ENTRY(path_entry)); SETPTR(local_prefs.project_file_path, g_strdup(str)); } static void add_stash_group(StashGroup *group, gboolean apply_defaults) { GKeyFile *kf; stash_groups = g_slist_prepend(stash_groups, group); if (!apply_defaults) return; kf = g_key_file_new(); stash_group_load_from_key_file(group, kf); g_key_file_free(kf); } static void init_stash_prefs(void) { StashGroup *group; group = stash_group_new("indentation"); /* copy global defaults */ indentation = *editor_get_indent_prefs(NULL); stash_group_set_use_defaults(group, FALSE); add_stash_group(group, FALSE); stash_group_add_spin_button_integer(group, &indentation.width, "indent_width", 4, "spin_indent_width_project"); stash_group_add_radio_buttons(group, (gint*)(gpointer)&indentation.type, "indent_type", GEANY_INDENT_TYPE_TABS, "radio_indent_spaces_project", GEANY_INDENT_TYPE_SPACES, "radio_indent_tabs_project", GEANY_INDENT_TYPE_TABS, "radio_indent_both_project", GEANY_INDENT_TYPE_BOTH, NULL); /* This is a 'hidden' pref for backwards-compatibility */ stash_group_add_integer(group, &indentation.hard_tab_width, "indent_hard_tab_width", 8); stash_group_add_toggle_button(group, &indentation.detect_type, "detect_indent", FALSE, "check_detect_indent_type_project"); stash_group_add_toggle_button(group, &indentation.detect_width, "detect_indent_width", FALSE, "check_detect_indent_width_project"); stash_group_add_combo_box(group, (gint*)(gpointer)&indentation.auto_indent_mode, "indent_mode", GEANY_AUTOINDENT_CURRENTCHARS, "combo_auto_indent_mode_project"); group = stash_group_new("file_prefs"); stash_group_add_toggle_button(group, &priv.final_new_line, "final_new_line", file_prefs.final_new_line, "check_new_line1"); stash_group_add_toggle_button(group, &priv.ensure_convert_new_lines, "ensure_convert_new_lines", file_prefs.ensure_convert_new_lines, "check_ensure_convert_new_lines1"); stash_group_add_toggle_button(group, &priv.strip_trailing_spaces, "strip_trailing_spaces", file_prefs.strip_trailing_spaces, "check_trailing_spaces1"); stash_group_add_toggle_button(group, &priv.replace_tabs, "replace_tabs", file_prefs.replace_tabs, "check_replace_tabs1"); add_stash_group(group, TRUE); group = stash_group_new("editor"); stash_group_add_toggle_button(group, &priv.line_wrapping, "line_wrapping", editor_prefs.line_wrapping, "check_line_wrapping1"); stash_group_add_spin_button_integer(group, &priv.line_break_column, "line_break_column", editor_prefs.line_break_column, "spin_line_break1"); stash_group_add_toggle_button(group, &priv.auto_continue_multiline, "auto_continue_multiline", editor_prefs.auto_continue_multiline, "check_auto_multiline1"); add_stash_group(group, TRUE); } #define COPY_PREF(dest, prefname)\ (dest.prefname = priv.prefname) const GeanyFilePrefs *project_get_file_prefs(void) { static GeanyFilePrefs fp; if (!app->project) return &file_prefs; fp = file_prefs; COPY_PREF(fp, final_new_line); COPY_PREF(fp, ensure_convert_new_lines); COPY_PREF(fp, strip_trailing_spaces); COPY_PREF(fp, replace_tabs); return &fp; } void project_init(void) { } void project_finalize(void) { } geany-2.0/src/keybindings.h0000644000175000017500000003571014514252267012663 00000000000000/* * keybindings.h - this file is part of Geany, a fast and lightweight IDE * * Copyright 2006 The Geany contributors * * This program 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; either version 2 of the License, or * (at your option) any later version. * * This program 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef GEANY_KEYBINDINGS_H #define GEANY_KEYBINDINGS_H 1 #include "gtkcompat.h" G_BEGIN_DECLS /** Defines the primary modifier mask which is the Ctrl key mask on * UNIX/Windows and Command key mask on OS X. When testing for the mask * presence, use together with keybindings_get_modifiers() which adds * @c GEANY_PRIMARY_MOD_MASK when needed. * @since 1.25. */ #ifdef __APPLE__ #define GEANY_PRIMARY_MOD_MASK GDK_META_MASK #else #define GEANY_PRIMARY_MOD_MASK GDK_CONTROL_MASK #endif /** A collection of keybindings grouped together. */ typedef struct GeanyKeyGroup GeanyKeyGroup; typedef struct GeanyKeyBinding GeanyKeyBinding; /** Function pointer type used for keybinding group callbacks. * * You should return @c TRUE to indicate handling the callback. (Occasionally, if the keybinding * cannot apply in the current situation, it is useful to return @c FALSE to allow a later keybinding * with the same key combination to handle it). */ typedef gboolean (*GeanyKeyGroupCallback) (guint key_id); /** Function pointer type used for keybinding group callbacks, with userdata for passing context. * * You should return @c TRUE to indicate handling the callback. (Occasionally, if the keybinding * cannot apply in the current situation, it is useful to return @c FALSE to allow a later keybinding * with the same key combination to handle it). * * @since 1.26 (API 226) */ typedef gboolean (*GeanyKeyGroupFunc)(GeanyKeyGroup *group, guint key_id, gpointer user_data); /** Function pointer type used for keybinding callbacks. */ typedef void (*GeanyKeyCallback) (guint key_id); /** Function pointer type used for keybinding callbacks, with userdata for passing context * * You should return @c TRUE to indicate handling the callback. (Occasionally, if the keybinding * cannot apply in the current situation, it is useful to return @c FALSE to allow a later keybinding * with the same key combination to handle it). * * @since 1.26 (API 226) */ typedef gboolean (*GeanyKeyBindingFunc)(GeanyKeyBinding *key, guint key_id, gpointer user_data); /** Represents a single keybinding action. * * Use keybindings_set_item() to set. */ struct GeanyKeyBinding { guint key; /**< Key value in lower-case, such as @c GDK_KEY_a or 0 */ GdkModifierType mods; /**< Modifier keys, such as @c GDK_CONTROL_MASK or 0 */ gchar *name; /**< Key name for the configuration file, such as @c "menu_new" */ /** Label used in the preferences dialog keybindings tab. * May contain underscores - these won't be displayed. */ gchar *label; /** Function called when the key combination is pressed, or @c NULL to use the group callback * (preferred). @see plugin_set_key_group(). */ GeanyKeyCallback callback; GtkWidget *menu_item; /**< Optional widget to set an accelerator for, or @c NULL */ guint id; guint default_key; GdkModifierType default_mods; GeanyKeyBindingFunc cb_func; gpointer cb_data; GDestroyNotify cb_data_destroy; }; /* Note: we don't need to break the plugin ABI when appending keybinding or keygroup IDs, * just make sure to insert immediately before the _COUNT item, so * the existing enum values stay the same. */ /** Keybinding group IDs for use with keybindings_send_command(). */ /* These IDs are used to lookup a group. */ enum GeanyKeyGroupID { GEANY_KEY_GROUP_FILE, /**< Group. */ GEANY_KEY_GROUP_PROJECT, /**< Group. */ GEANY_KEY_GROUP_EDITOR, /**< Group. */ GEANY_KEY_GROUP_CLIPBOARD, /**< Group. */ GEANY_KEY_GROUP_SELECT, /**< Group. */ GEANY_KEY_GROUP_FORMAT, /**< Group. */ GEANY_KEY_GROUP_INSERT, /**< Group. */ GEANY_KEY_GROUP_SETTINGS, /**< Group. */ GEANY_KEY_GROUP_SEARCH, /**< Group. */ GEANY_KEY_GROUP_GOTO, /**< Group. */ GEANY_KEY_GROUP_VIEW, /**< Group. */ GEANY_KEY_GROUP_FOCUS, /**< Group. */ GEANY_KEY_GROUP_NOTEBOOK, /**< Group. */ GEANY_KEY_GROUP_DOCUMENT, /**< Group. */ GEANY_KEY_GROUP_BUILD, /**< Group. */ GEANY_KEY_GROUP_TOOLS, /**< Group. */ GEANY_KEY_GROUP_HELP, /**< Group. */ GEANY_KEY_GROUP_COUNT /* must not be used by plugins */ }; /** Keybinding command IDs for use with keybindings_send_command(). */ /* These IDs are used to lookup a keybinding. */ enum GeanyKeyBindingID { GEANY_KEYS_EDITOR_TRANSPOSELINE, /**< Keybinding. */ GEANY_KEYS_DOCUMENT_REMOVE_ERROR_INDICATORS, /**< Keybinding. */ GEANY_KEYS_FOCUS_SEARCHBAR, /**< Keybinding. */ GEANY_KEYS_SEARCH_FIND, /**< Keybinding. */ GEANY_KEYS_FILE_SAVEALL, /**< Keybinding. */ GEANY_KEYS_GOTO_NEXTMARKER, /**< Keybinding. */ GEANY_KEYS_NOTEBOOK_SWITCHTABLEFT, /**< Keybinding. */ GEANY_KEYS_VIEW_ZOOMOUT, /**< Keybinding. */ GEANY_KEYS_GOTO_LINE, /**< Keybinding. */ GEANY_KEYS_DOCUMENT_TOGGLEFOLD, /**< Keybinding. */ GEANY_KEYS_BUILD_COMPILE, /**< Keybinding. */ GEANY_KEYS_EDITOR_SCROLLTOLINE, /**< Keybinding. */ GEANY_KEYS_DOCUMENT_UNFOLDALL, /**< Keybinding. */ GEANY_KEYS_GOTO_MATCHINGBRACE, /**< Keybinding. */ GEANY_KEYS_SEARCH_FINDDOCUMENTUSAGE, /**< Keybinding. */ GEANY_KEYS_CLIPBOARD_PASTE, /**< Keybinding. */ GEANY_KEYS_BUILD_MAKE, /**< Keybinding. */ GEANY_KEYS_INSERT_ALTWHITESPACE, /**< Keybinding. */ GEANY_KEYS_EDITOR_SCROLLLINEDOWN, /**< Keybinding. */ GEANY_KEYS_VIEW_TOGGLEALL, /**< Keybinding. */ GEANY_KEYS_VIEW_FULLSCREEN, /**< Keybinding. */ GEANY_KEYS_GOTO_LINEEND, /**< Keybinding. */ GEANY_KEYS_EDITOR_CALLTIP, /**< Keybinding. */ GEANY_KEYS_FILE_PRINT, /**< Keybinding. */ GEANY_KEYS_EDITOR_DUPLICATELINE, /**< Keybinding. */ GEANY_KEYS_FOCUS_SCRIBBLE, /**< Keybinding. */ GEANY_KEYS_TOOLS_OPENCOLORCHOOSER, /**< Keybinding. */ GEANY_KEYS_SEARCH_PREVIOUSMESSAGE, /**< Keybinding. */ GEANY_KEYS_FILE_CLOSE, /**< Keybinding. */ GEANY_KEYS_DOCUMENT_REPLACETABS, /**< Keybinding. */ GEANY_KEYS_FILE_RELOAD, /**< Keybinding. */ GEANY_KEYS_SEARCH_FINDNEXTSEL, /**< Keybinding. */ GEANY_KEYS_FOCUS_MESSAGES, /**< Keybinding. */ GEANY_KEYS_BUILD_RUN, /**< Keybinding. */ GEANY_KEYS_HELP_HELP, /**< Keybinding. */ GEANY_KEYS_SETTINGS_PLUGINPREFERENCES, /**< Keybinding. */ GEANY_KEYS_VIEW_ZOOMRESET, /**< Keybinding. */ GEANY_KEYS_SELECT_WORD, /**< Keybinding. */ GEANY_KEYS_FORMAT_INCREASEINDENT, /**< Keybinding. */ GEANY_KEYS_SETTINGS_PREFERENCES, /**< Keybinding. */ GEANY_KEYS_FORMAT_SENDTOCMD3, /**< Keybinding. */ GEANY_KEYS_DOCUMENT_FOLDALL, /**< Keybinding. */ GEANY_KEYS_FORMAT_SENDTOVTE, /**< Keybinding. */ GEANY_KEYS_PROJECT_PROPERTIES, /**< Keybinding. */ GEANY_KEYS_DOCUMENT_LINEWRAP, /**< Keybinding. */ GEANY_KEYS_EDITOR_MACROLIST, /**< Keybinding. * @deprecated 1.25, it doesn't do anything anymore */ GEANY_KEYS_EDITOR_SUPPRESSSNIPPETCOMPLETION, /**< Keybinding. */ GEANY_KEYS_FOCUS_SIDEBAR_SYMBOL_LIST, /**< Keybinding. */ GEANY_KEYS_GOTO_LINESTART, /**< Keybinding. */ GEANY_KEYS_SEARCH_FINDUSAGE, /**< Keybinding. */ GEANY_KEYS_FILE_NEW, /**< Keybinding. */ GEANY_KEYS_EDITOR_SNIPPETNEXTCURSOR, /**< Keybinding. */ GEANY_KEYS_NOTEBOOK_SWITCHTABRIGHT, /**< Keybinding. */ GEANY_KEYS_FILE_SAVE, /**< Keybinding. */ GEANY_KEYS_FORMAT_INCREASEINDENTBYSPACE, /**< Keybinding. */ GEANY_KEYS_SEARCH_FINDNEXT, /**< Keybinding. */ GEANY_KEYS_GOTO_TOGGLEMARKER, /**< Keybinding. */ GEANY_KEYS_GOTO_TAGDEFINITION, /**< Keybinding. */ GEANY_KEYS_SEARCH_NEXTMESSAGE, /**< Keybinding. */ GEANY_KEYS_EDITOR_DELETELINETOEND, /**< Keybinding. */ GEANY_KEYS_FORMAT_AUTOINDENT, /**< Keybinding. */ GEANY_KEYS_FILE_OPENSELECTED, /**< Keybinding. */ GEANY_KEYS_GOTO_BACK, /**< Keybinding. */ GEANY_KEYS_INSERT_DATE, /**< Keybinding. */ GEANY_KEYS_BUILD_PREVIOUSERROR, /**< Keybinding. */ GEANY_KEYS_GOTO_LINEENDVISUAL, /**< Keybinding. */ GEANY_KEYS_DOCUMENT_REPLACESPACES, /**< Keybinding. */ GEANY_KEYS_FOCUS_EDITOR, /**< Keybinding. */ GEANY_KEYS_SELECT_WORDPARTRIGHT, /**< Keybinding. */ GEANY_KEYS_VIEW_MESSAGEWINDOW, /**< Keybinding. */ GEANY_KEYS_FOCUS_SIDEBAR_DOCUMENT_LIST, /**< Keybinding. */ GEANY_KEYS_FORMAT_REFLOWPARAGRAPH, /**< Keybinding. */ GEANY_KEYS_EDITOR_MOVELINEUP, /**< Keybinding. */ GEANY_KEYS_NOTEBOOK_MOVETABLEFT, /**< Keybinding. */ GEANY_KEYS_SELECT_LINE, /**< Keybinding. */ GEANY_KEYS_EDITOR_UNDO, /**< Keybinding. */ GEANY_KEYS_EDITOR_MOVELINEDOWN, /**< Keybinding. */ GEANY_KEYS_CLIPBOARD_COPYLINE, /**< Keybinding. */ GEANY_KEYS_BUILD_MAKEOWNTARGET, /**< Keybinding. */ GEANY_KEYS_FORMAT_SENDTOCMD2, /**< Keybinding. */ GEANY_KEYS_SEARCH_MARKALL, /**< Keybinding. */ GEANY_KEYS_BUILD_LINK, /**< Keybinding. */ GEANY_KEYS_FILE_CLOSEALL, /**< Keybinding. */ GEANY_KEYS_GOTO_FORWARD, /**< Keybinding. */ GEANY_KEYS_CLIPBOARD_CUT, /**< Keybinding. */ GEANY_KEYS_NOTEBOOK_SWITCHTABLASTUSED, /**< Keybinding. */ GEANY_KEYS_NOTEBOOK_MOVETABRIGHT, /**< Keybinding. */ GEANY_KEYS_BUILD_OPTIONS, /**< Keybinding. */ GEANY_KEYS_GOTO_TAGDECLARATION, /**< Keybinding. */ GEANY_KEYS_FILE_OPEN, /**< Keybinding. */ GEANY_KEYS_EDITOR_COMPLETESNIPPET, /**< Keybinding. */ GEANY_KEYS_FORMAT_UNCOMMENTLINE, /**< Keybinding. */ GEANY_KEYS_FOCUS_VTE, /**< Keybinding. */ GEANY_KEYS_FORMAT_SENDTOCMD1, /**< Keybinding. */ GEANY_KEYS_SELECT_WORDPARTLEFT, /**< Keybinding. */ GEANY_KEYS_VIEW_ZOOMIN, /**< Keybinding. */ GEANY_KEYS_DOCUMENT_LINEBREAK, /**< Keybinding. */ GEANY_KEYS_EDITOR_REDO, /**< Keybinding. */ GEANY_KEYS_EDITOR_CONTEXTACTION, /**< Keybinding. */ GEANY_KEYS_SEARCH_FINDPREVSEL, /**< Keybinding. */ GEANY_KEYS_FORMAT_DECREASEINDENTBYSPACE, /**< Keybinding. */ GEANY_KEYS_FORMAT_COMMENTLINETOGGLE, /**< Keybinding. */ GEANY_KEYS_SELECT_ALL, /**< Keybinding. */ GEANY_KEYS_DOCUMENT_RELOADTAGLIST, /**< Keybinding. */ GEANY_KEYS_BUILD_NEXTERROR, /**< Keybinding. */ GEANY_KEYS_NOTEBOOK_MOVETABLAST, /**< Keybinding. */ GEANY_KEYS_SELECT_PARAGRAPH, /**< Keybinding. */ GEANY_KEYS_EDITOR_DELETELINE, /**< Keybinding. */ GEANY_KEYS_CLIPBOARD_COPY, /**< Keybinding. */ GEANY_KEYS_VIEW_SIDEBAR, /**< Keybinding. */ GEANY_KEYS_FILE_SAVEAS, /**< Keybinding. */ GEANY_KEYS_FORMAT_COMMENTLINE, /**< Keybinding. */ GEANY_KEYS_GOTO_PREVWORDPART, /**< Keybinding. */ GEANY_KEYS_SEARCH_FINDPREVIOUS, /**< Keybinding. */ GEANY_KEYS_SEARCH_REPLACE, /**< Keybinding. */ GEANY_KEYS_EDITOR_WORDPARTCOMPLETION, /**< Keybinding. */ GEANY_KEYS_EDITOR_AUTOCOMPLETE, /**< Keybinding. */ GEANY_KEYS_FOCUS_SIDEBAR, /**< Keybinding. */ GEANY_KEYS_FOCUS_MESSAGE_WINDOW, /**< Keybinding. */ GEANY_KEYS_NOTEBOOK_MOVETABFIRST, /**< Keybinding. */ GEANY_KEYS_GOTO_PREVIOUSMARKER, /**< Keybinding. */ GEANY_KEYS_EDITOR_SCROLLLINEUP, /**< Keybinding. */ GEANY_KEYS_FOCUS_COMPILER, /**< Keybinding. */ GEANY_KEYS_FORMAT_TOGGLECASE, /**< Keybinding. */ GEANY_KEYS_CLIPBOARD_CUTLINE, /**< Keybinding. */ GEANY_KEYS_DOCUMENT_REMOVE_MARKERS, /**< Keybinding. */ GEANY_KEYS_BUILD_MAKEOBJECT, /**< Keybinding. */ GEANY_KEYS_FORMAT_DECREASEINDENT, /**< Keybinding. */ GEANY_KEYS_FILE_OPENLASTTAB, /**< Keybinding. */ GEANY_KEYS_SEARCH_FINDINFILES, /**< Keybinding. */ GEANY_KEYS_GOTO_NEXTWORDPART, /**< Keybinding. */ GEANY_KEYS_INSERT_LINEAFTER, /**< Keybinding. */ GEANY_KEYS_INSERT_LINEBEFORE, /**< Keybinding. */ GEANY_KEYS_DOCUMENT_REMOVE_MARKERS_INDICATORS, /**< Keybinding. */ GEANY_KEYS_PROJECT_OPEN, /**< Keybinding. */ GEANY_KEYS_PROJECT_NEW, /**< Keybinding. */ GEANY_KEYS_PROJECT_CLOSE, /**< Keybinding. */ GEANY_KEYS_FORMAT_JOINLINES, /**< Keybinding. */ GEANY_KEYS_GOTO_LINESTARTVISUAL, /**< Keybinding. */ GEANY_KEYS_DOCUMENT_CLONE, /**< Keybinding. */ GEANY_KEYS_FILE_QUIT, /**< Keybinding. */ GEANY_KEYS_FILE_PROPERTIES, /**< Keybinding. */ GEANY_KEYS_FORMAT_SENDTOCMD4, /**< Keybinding. */ GEANY_KEYS_FORMAT_SENDTOCMD5, /**< Keybinding. */ GEANY_KEYS_FORMAT_SENDTOCMD6, /**< Keybinding. */ GEANY_KEYS_FORMAT_SENDTOCMD7, /**< Keybinding. */ GEANY_KEYS_FORMAT_SENDTOCMD8, /**< Keybinding. */ GEANY_KEYS_FORMAT_SENDTOCMD9, /**< Keybinding. */ GEANY_KEYS_EDITOR_DELETELINETOBEGINNING, /**< Keybinding. */ GEANY_KEYS_DOCUMENT_STRIPTRAILINGSPACES, /**< Keybinding. * @since 1.34 (API 238) */ GEANY_KEYS_FILE_RELOAD_ALL, /**< Keybinding. * @since 1.38 (API 240) */ GEANY_KEYS_PROJECT_NEW_FROM_FOLDER, /**< Keybinding. * @since 2.0 (API 243) */ GEANY_KEYS_COUNT /* must not be used by plugins */ }; void keybindings_send_command(guint group_id, guint key_id); GeanyKeyBinding *keybindings_set_item(GeanyKeyGroup *group, gsize key_id, GeanyKeyCallback callback, guint key, GdkModifierType mod, const gchar *name, const gchar *label, GtkWidget *menu_item); GeanyKeyBinding *keybindings_set_item_full(GeanyKeyGroup *group, gsize key_id, guint key, GdkModifierType mod, const gchar *kf_name, const gchar *label, GtkWidget *menu_item, GeanyKeyBindingFunc func, gpointer pdata, GDestroyNotify destroy_notify); GeanyKeyBinding *keybindings_get_item(GeanyKeyGroup *group, gsize key_id); GdkModifierType keybindings_get_modifiers(GdkModifierType mods); void keybindings_load_keyfile(void); #ifdef GEANY_PRIVATE extern GPtrArray *keybinding_groups; /* array of GeanyKeyGroup pointers */ void keybindings_init(void); void keybindings_free(void); GeanyKeyGroup *keybindings_get_core_group(guint id); GeanyKeyGroup *keybindings_set_group(GeanyKeyGroup *group, const gchar *section_name, const gchar *label, gsize count, GeanyKeyGroupCallback callback) G_GNUC_WARN_UNUSED_RESULT; void keybindings_free_group(GeanyKeyGroup *group); gchar *keybindings_get_label(GeanyKeyBinding *kb); void keybindings_update_combo(GeanyKeyBinding *kb, guint key, GdkModifierType mods); GeanyKeyBinding *keybindings_lookup_item(guint group_id, guint key_id); /* just write the content of the keys array to the config file */ void keybindings_write_to_file(void); void keybindings_show_shortcuts(void); gboolean keybindings_check_event(GdkEventKey *ev, GeanyKeyBinding *kb); void keybindings_dialog_show_prefs_scroll(const gchar *name); #endif /* GEANY_PRIVATE */ G_END_DECLS #endif /* GEANY_KEYBINDINGS_H */ geany-2.0/src/notebook.h0000644000175000017500000000310414514252267012165 00000000000000/* * notebook.h - this file is part of Geany, a fast and lightweight IDE * * Copyright 2006 The Geany contributors * * This program 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; either version 2 of the License, or * (at your option) any later version. * * This program 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef GEANY_NOTEBOOK_H #define GEANY_NOTEBOOK_H 1 #include "document.h" #include G_BEGIN_DECLS void notebook_init(void); void notebook_free(void); /* Returns page number of notebook page, or -1 on error */ gint notebook_new_tab(GeanyDocument *doc); /* Always use this instead of gtk_notebook_remove_page(). */ void notebook_remove_page(gint page_num); /* Switch notebook to the last used tab. Can be called repeatedly to get to the * previous tabs. */ void notebook_switch_tablastused(void); /* Returns TRUE when MRU tab switch is in progress (i.e. not at the final * document yet). */ gboolean notebook_switch_in_progress(void); G_END_DECLS #endif /* GEANY_NOTEBOOK_H */ geany-2.0/src/ui_utils.c0000644000175000017500000027242214514252267012210 00000000000000/* * ui_utils.c - this file is part of Geany, a fast and lightweight IDE * * Copyright 2006 The Geany contributors * * This program 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; either version 2 of the License, or * (at your option) any later version. * * This program 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /** @file ui_utils.h * User Interface general utility functions. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include "ui_utils.h" #include "app.h" #include "callbacks.h" #include "dialogs.h" #include "documentprivate.h" #include "encodingsprivate.h" #include "filetypes.h" #include "geanymenubuttonaction.h" #include "keyfile.h" #include "keybindings.h" #include "main.h" #include "msgwindow.h" #include "prefs.h" #include "project.h" #include "sciwrappers.h" #include "sidebar.h" #include "stash.h" #include "support.h" #include "symbols.h" #include "toolbar.h" #include "utils.h" #include "win32.h" #include "osx.h" #include #include #include #include #include #define DEFAULT_STATUSBAR_TEMPLATE N_(\ "line: %l / %L\t " \ "col: %c\t " \ "sel: %s\t " \ "%w %t %m" \ "EOL: %M " \ "encoding: %e " \ "filetype: %f " \ "scope: %S") GEANY_EXPORT_SYMBOL GeanyInterfacePrefs interface_prefs; GeanyMainWidgets main_widgets; UIPrefs ui_prefs; UIWidgets ui_widgets; static GtkBuilder *builder = NULL; static GtkWidget* window1 = NULL; static GtkWidget* toolbar_popup_menu1 = NULL; static GtkWidget* edit_menu1 = NULL; static GtkWidget* prefs_dialog = NULL; static GtkWidget* project_dialog = NULL; static struct { /* pointers to widgets only sensitive when there is at least one document, the pointers can * also be GtkAction objects, so check each pointer before using it */ GPtrArray *document_buttons; GtkWidget *menu_insert_include_items[2]; GtkWidget *popup_goto_items[4]; GtkWidget *popup_copy_items[3]; GtkWidget *menu_copy_items[3]; GtkWidget *redo_items[3]; GtkWidget *undo_items[3]; GtkWidget *save_buttons[4]; GtkWidget *config_files_menu; } widgets; enum { RECENT_FILE_FILE, RECENT_FILE_PROJECT }; typedef struct { gint type; GQueue *recent_queue; GtkWidget *menubar; GtkWidget *toolbar; void (*activate_cb)(GtkMenuItem *, gpointer); } GeanyRecentFiles; static void update_recent_menu(GeanyRecentFiles *grf); static void recent_file_loaded(const gchar *utf8_filename, GeanyRecentFiles *grf); static void recent_file_activate_cb(GtkMenuItem *menuitem, gpointer user_data); static void recent_project_activate_cb(GtkMenuItem *menuitem, gpointer user_data); static GtkWidget *progress_bar_create(void); /* simple wrapper for gtk_widget_set_sensitive() to allow widget being NULL */ void ui_widget_set_sensitive(GtkWidget *widget, gboolean set) { if (widget != NULL) gtk_widget_set_sensitive(widget, set); } /* allow_override is TRUE if text can be ignored when another message has been set * that didn't use allow_override and has not timed out. */ static void set_statusbar(const gchar *text, gboolean allow_override) { static guint id = 0; static glong last_time = 0; GTimeVal timeval; const gint GEANY_STATUS_TIMEOUT = 1; if (! interface_prefs.statusbar_visible) return; /* just do nothing if statusbar is not visible */ if (id == 0) id = gtk_statusbar_get_context_id(GTK_STATUSBAR(ui_widgets.statusbar), "geany-main"); g_get_current_time(&timeval); if (! allow_override) { gtk_statusbar_pop(GTK_STATUSBAR(ui_widgets.statusbar), id); gtk_statusbar_push(GTK_STATUSBAR(ui_widgets.statusbar), id, text); last_time = timeval.tv_sec; } else if (timeval.tv_sec > last_time + GEANY_STATUS_TIMEOUT) { gtk_statusbar_pop(GTK_STATUSBAR(ui_widgets.statusbar), id); gtk_statusbar_push(GTK_STATUSBAR(ui_widgets.statusbar), id, text); } } /** Displays text on the statusbar. * @param log Whether the message should be recorded in the Status window. * @param format A @c printf -style string. */ GEANY_API_SYMBOL void ui_set_statusbar(gboolean log, const gchar *format, ...) { gchar *string; va_list args; va_start(args, format); string = g_strdup_vprintf(format, args); va_end(args); if (! prefs.suppress_status_messages) set_statusbar(string, FALSE); if (log || prefs.suppress_status_messages) msgwin_status_add("%s", string); g_free(string); } /* note: some comments below are for translators */ static gchar *create_statusbar_statistics(GeanyDocument *doc, guint line, guint vcol, guint pos) { const gchar *cur_tag; const gchar *fmt; const gchar *expos; /* % expansion position */ const gchar sp[] = " "; GString *stats_str; ScintillaObject *sci = doc->editor->sci; if (!EMPTY(ui_prefs.statusbar_template)) fmt = ui_prefs.statusbar_template; else fmt = _(DEFAULT_STATUSBAR_TEMPLATE); stats_str = g_string_sized_new(120); while ((expos = strchr(fmt, '%')) != NULL) { /* append leading text before % char */ g_string_append_len(stats_str, fmt, expos - fmt); switch (*++expos) { case 'l': g_string_append_printf(stats_str, "%d", line + 1); break; case 'L': g_string_append_printf(stats_str, "%d", sci_get_line_count(doc->editor->sci)); break; case 'c': g_string_append_printf(stats_str, "%d", vcol); break; case 'C': g_string_append_printf(stats_str, "%d", vcol + 1); break; case 'p': g_string_append_printf(stats_str, "%u", pos); break; case 's': { gint len = sci_get_selected_text_length2(sci); /* check if whole lines are selected */ if (!len || sci_get_col_from_position(sci, sci_get_selection_start(sci)) != 0 || sci_get_col_from_position(sci, sci_get_selection_end(sci)) != 0) g_string_append_printf(stats_str, "%d", len); else /* L = lines */ g_string_append_printf(stats_str, _("%dL"), sci_get_lines_selected(doc->editor->sci) - 1); break; } case 'n' : g_string_append_printf(stats_str, "%d", sci_get_selected_text_length2(doc->editor->sci)); break; case 'w': /* RO = read-only */ g_string_append(stats_str, (doc->readonly) ? _("RO ") : /* OVR = overwrite/overtype, INS = insert */ (sci_get_overtype(doc->editor->sci) ? _("OVR") : _("INS"))); break; case 'r': if (doc->readonly) { g_string_append(stats_str, _("RO ")); /* RO = read-only */ g_string_append(stats_str, sp + 1); } break; case 't': { switch (editor_get_indent_prefs(doc->editor)->type) { case GEANY_INDENT_TYPE_TABS: g_string_append(stats_str, _("TAB")); break; case GEANY_INDENT_TYPE_SPACES: /* SP = space */ g_string_append(stats_str, _("SP")); break; case GEANY_INDENT_TYPE_BOTH: /* T/S = tabs and spaces */ g_string_append(stats_str, _("T/S")); break; } break; } case 'm': if (doc->changed) { g_string_append(stats_str, _("MOD")); /* MOD = modified */ g_string_append(stats_str, sp); } break; case 'M': g_string_append(stats_str, utils_get_eol_short_name(sci_get_eol_mode(doc->editor->sci))); break; case 'e': g_string_append(stats_str, doc->encoding ? doc->encoding : _("unknown")); if (encodings_is_unicode_charset(doc->encoding) && (doc->has_bom)) { g_string_append_c(stats_str, ' '); g_string_append(stats_str, _("(with BOM)")); /* BOM = byte order mark */ } break; case 'f': g_string_append(stats_str, filetypes_get_display_name(doc->file_type)); break; case 'S': symbols_get_current_scope(doc, &cur_tag); g_string_append(stats_str, cur_tag); break; case 'Y': g_string_append_c(stats_str, ' '); g_string_append_printf(stats_str, "%d", sci_get_style_at(doc->editor->sci, pos)); break; default: g_string_append_len(stats_str, expos, 1); } /* skip past %c chars */ if (*expos) fmt = expos + 1; else break; } /* add any remaining text */ g_string_append(stats_str, fmt); return g_string_free(stats_str, FALSE); } /* updates the status bar document statistics */ void ui_update_statusbar(GeanyDocument *doc, gint pos) { g_return_if_fail(doc == NULL || doc->is_valid); if (! interface_prefs.statusbar_visible) return; /* just do nothing if statusbar is not visible */ if (doc == NULL) doc = document_get_current(); if (doc != NULL) { guint line, vcol; gchar *stats_str; if (pos == -1) pos = sci_get_current_position(doc->editor->sci); line = sci_get_line_from_position(doc->editor->sci, pos); /* Add temporary fix for sci infinite loop in Document::GetColumn(int) * when current pos is beyond document end (can occur when removing * blocks of selected lines especially esp. brace sections near end of file). */ if (pos <= sci_get_length(doc->editor->sci)) vcol = sci_get_col_from_position(doc->editor->sci, pos); else vcol = 0; vcol += sci_get_cursor_virtual_space(doc->editor->sci); stats_str = create_statusbar_statistics(doc, line, vcol, pos); /* can be overridden by status messages */ set_statusbar(stats_str, TRUE); g_free(stats_str); } else /* no documents */ { set_statusbar("", TRUE); /* can be overridden by status messages */ } } /* This sets the window title according to the current filename. */ void ui_set_window_title(GeanyDocument *doc) { GString *str; GeanyProject *project = app->project; g_return_if_fail(doc == NULL || doc->is_valid); if (doc == NULL) doc = document_get_current(); str = g_string_new(NULL); if (doc != NULL) { g_string_append(str, doc->changed ? "*" : ""); if (doc->file_name == NULL) g_string_append(str, DOC_FILENAME(doc)); else { gchar *short_name = document_get_basename_for_display(doc, interface_prefs.tab_label_len); gchar *dirname = g_path_get_dirname(DOC_FILENAME(doc)); g_string_append(str, short_name); g_string_append(str, " - "); g_string_append(str, dirname ? dirname : ""); g_free(short_name); g_free(dirname); } g_string_append(str, " - "); } if (project) { g_string_append_c(str, '['); g_string_append(str, project->name); g_string_append(str, "] - "); } g_string_append(str, "Geany"); if (cl_options.new_instance) { g_string_append(str, _(" (new instance)")); } gtk_window_set_title(GTK_WINDOW(main_widgets.window), str->str); g_string_free(str, TRUE); } void ui_set_editor_font(const gchar *font_name) { guint i; g_return_if_fail(font_name != NULL); /* do nothing if font has not changed */ if (interface_prefs.editor_font != NULL) if (strcmp(font_name, interface_prefs.editor_font) == 0) return; g_free(interface_prefs.editor_font); interface_prefs.editor_font = g_strdup(font_name); /* We copy the current style, and update the font in all open tabs. */ for (i = 0; i < documents_array->len; i++) { if (documents[i]->editor) { editor_set_font(documents[i]->editor, interface_prefs.editor_font); } } ui_set_statusbar(TRUE, _("Font updated (%s)."), interface_prefs.editor_font); } void ui_set_fullscreen(void) { if (ui_prefs.fullscreen) { gtk_window_fullscreen(GTK_WINDOW(main_widgets.window)); } else { gtk_window_unfullscreen(GTK_WINDOW(main_widgets.window)); } } void ui_update_popup_reundo_items(GeanyDocument *doc) { gboolean enable_undo; gboolean enable_redo; guint i, len; g_return_if_fail(doc == NULL || doc->is_valid); if (doc == NULL) { enable_undo = FALSE; enable_redo = FALSE; } else { enable_undo = document_can_undo(doc); enable_redo = document_can_redo(doc); } /* index 0 is the popup menu, 1 is the menubar, 2 is the toolbar */ len = G_N_ELEMENTS(widgets.undo_items); for (i = 0; i < len; i++) { ui_widget_set_sensitive(widgets.undo_items[i], enable_undo); } len = G_N_ELEMENTS(widgets.redo_items); for (i = 0; i < len; i++) { ui_widget_set_sensitive(widgets.redo_items[i], enable_redo); } } void ui_update_popup_copy_items(GeanyDocument *doc) { gboolean enable; guint i, len; g_return_if_fail(doc == NULL || doc->is_valid); if (doc == NULL) enable = FALSE; else enable = sci_has_selection(doc->editor->sci); len = G_N_ELEMENTS(widgets.popup_copy_items); for (i = 0; i < len; i++) ui_widget_set_sensitive(widgets.popup_copy_items[i], enable); } void ui_update_popup_goto_items(gboolean enable) { guint i, len; len = G_N_ELEMENTS(widgets.popup_goto_items); for (i = 0; i < len; i++) ui_widget_set_sensitive(widgets.popup_goto_items[i], enable); } void ui_menu_copy_items_set_sensitive(gboolean sensitive) { guint i, len; len = G_N_ELEMENTS(widgets.menu_copy_items); for (i = 0; i < len; i++) ui_widget_set_sensitive(widgets.menu_copy_items[i], sensitive); } void ui_update_menu_copy_items(GeanyDocument *doc) { gboolean enable = FALSE; GtkWidget *focusw = gtk_window_get_focus(GTK_WINDOW(main_widgets.window)); g_return_if_fail(doc == NULL || doc->is_valid); if (IS_SCINTILLA(focusw)) enable = (doc == NULL) ? FALSE : sci_has_selection(doc->editor->sci); else if (GTK_IS_EDITABLE(focusw)) enable = gtk_editable_get_selection_bounds(GTK_EDITABLE(focusw), NULL, NULL); else if (GTK_IS_TEXT_VIEW(focusw)) { GtkTextBuffer *buffer = gtk_text_view_get_buffer( GTK_TEXT_VIEW(focusw)); enable = gtk_text_buffer_get_selection_bounds(buffer, NULL, NULL); } ui_menu_copy_items_set_sensitive(enable); } void ui_update_insert_include_item(GeanyDocument *doc, gint item) { gboolean enable = FALSE; g_return_if_fail(doc == NULL || doc->is_valid); if (doc == NULL || doc->file_type == NULL) enable = FALSE; else if (doc->file_type->id == GEANY_FILETYPES_C || doc->file_type->id == GEANY_FILETYPES_CPP) enable = TRUE; ui_widget_set_sensitive(widgets.menu_insert_include_items[item], enable); } void ui_update_fold_items(void) { ui_widget_show_hide(ui_lookup_widget(main_widgets.window, "menu_fold_all1"), editor_prefs.folding); ui_widget_show_hide(ui_lookup_widget(main_widgets.window, "menu_unfold_all1"), editor_prefs.folding); ui_widget_show_hide(ui_lookup_widget(main_widgets.window, "separator22"), editor_prefs.folding); } /* @include include name or NULL for empty with cursor ready for typing it */ static void insert_include(GeanyDocument *doc, gint pos, const gchar *include) { gint pos_after = -1; gchar *text; g_return_if_fail(doc != NULL); g_return_if_fail(pos == -1 || pos >= 0); if (pos == -1) pos = sci_get_current_position(doc->editor->sci); if (! include) { text = g_strdup("#include \"\"\n"); pos_after = pos + 10; } else { text = g_strconcat("#include <", include, ">\n", NULL); } sci_start_undo_action(doc->editor->sci); sci_insert_text(doc->editor->sci, pos, text); sci_end_undo_action(doc->editor->sci); g_free(text); if (pos_after >= 0) sci_goto_pos(doc->editor->sci, pos_after, FALSE); } static void on_popup_insert_include_activate(GtkMenuItem *menuitem, gpointer user_data) { insert_include(document_get_current(), editor_info.click_pos, user_data); } static void on_menu_insert_include_activate(GtkMenuItem *menuitem, gpointer user_data) { insert_include(document_get_current(), -1, user_data); } static void insert_include_items(GtkMenu *me, GtkMenu *mp, gchar **includes, gchar *label) { guint i = 0; GtkWidget *edit_menu, *edit_menu_item; GtkWidget *popup_menu, *popup_menu_item; edit_menu = gtk_menu_new(); popup_menu = gtk_menu_new(); edit_menu_item = gtk_menu_item_new_with_label(label); popup_menu_item = gtk_menu_item_new_with_label(label); gtk_menu_item_set_submenu(GTK_MENU_ITEM(edit_menu_item), edit_menu); gtk_menu_item_set_submenu(GTK_MENU_ITEM(popup_menu_item), popup_menu); while (includes[i] != NULL) { GtkWidget *tmp_menu = gtk_menu_item_new_with_label(includes[i]); GtkWidget *tmp_popup = gtk_menu_item_new_with_label(includes[i]); gtk_container_add(GTK_CONTAINER(edit_menu), tmp_menu); gtk_container_add(GTK_CONTAINER(popup_menu), tmp_popup); g_signal_connect(tmp_menu, "activate", G_CALLBACK(on_menu_insert_include_activate), (gpointer) includes[i]); g_signal_connect(tmp_popup, "activate", G_CALLBACK(on_popup_insert_include_activate), (gpointer) includes[i]); i++; } gtk_widget_show_all(edit_menu_item); gtk_widget_show_all(popup_menu_item); gtk_container_add(GTK_CONTAINER(me), edit_menu_item); gtk_container_add(GTK_CONTAINER(mp), popup_menu_item); } void ui_create_insert_menu_items(void) { GtkMenu *menu_edit = GTK_MENU(ui_lookup_widget(main_widgets.window, "insert_include2_menu")); GtkMenu *menu_popup = GTK_MENU(ui_lookup_widget(main_widgets.editor_menu, "insert_include1_menu")); GtkWidget *blank; const gchar *c_includes_stdlib[] = { "assert.h", "ctype.h", "errno.h", "float.h", "limits.h", "locale.h", "math.h", "setjmp.h", "signal.h", "stdarg.h", "stddef.h", "stdio.h", "stdlib.h", "string.h", "time.h", NULL }; const gchar *c_includes_c99[] = { "complex.h", "fenv.h", "inttypes.h", "iso646.h", "stdbool.h", "stdint.h", "tgmath.h", "wchar.h", "wctype.h", NULL }; const gchar *c_includes_cpp[] = { "cstdio", "cstring", "cctype", "cmath", "ctime", "cstdlib", "cstdarg", NULL }; const gchar *c_includes_cppstdlib[] = { "iostream", "fstream", "iomanip", "sstream", "exception", "stdexcept", "memory", "locale", NULL }; const gchar *c_includes_stl[] = { "bitset", "deque", "list", "map", "set", "queue", "stack", "vector", "algorithm", "iterator", "functional", "string", "complex", "valarray", NULL }; blank = gtk_menu_item_new_with_label("#include \"...\""); gtk_container_add(GTK_CONTAINER(menu_edit), blank); gtk_widget_show(blank); g_signal_connect(blank, "activate", G_CALLBACK(on_menu_insert_include_activate), NULL); blank = gtk_separator_menu_item_new (); gtk_container_add(GTK_CONTAINER(menu_edit), blank); gtk_widget_show(blank); blank = gtk_menu_item_new_with_label("#include \"...\""); gtk_container_add(GTK_CONTAINER(menu_popup), blank); gtk_widget_show(blank); g_signal_connect(blank, "activate", G_CALLBACK(on_popup_insert_include_activate), NULL); blank = gtk_separator_menu_item_new(); gtk_container_add(GTK_CONTAINER(menu_popup), blank); gtk_widget_show(blank); insert_include_items(menu_edit, menu_popup, (gchar**) c_includes_stdlib, _("C Standard Library")); insert_include_items(menu_edit, menu_popup, (gchar**) c_includes_c99, _("ISO C99")); insert_include_items(menu_edit, menu_popup, (gchar**) c_includes_cpp, _("C++ (C Standard Library)")); insert_include_items(menu_edit, menu_popup, (gchar**) c_includes_cppstdlib, _("C++ Standard Library")); insert_include_items(menu_edit, menu_popup, (gchar**) c_includes_stl, _("C++ STL")); } static void insert_date(GeanyDocument *doc, gint pos, const gchar *date_style) { const gchar *format = NULL; gchar *time_str; g_return_if_fail(doc != NULL); g_return_if_fail(pos == -1 || pos >= 0); if (pos == -1) pos = sci_get_current_position(doc->editor->sci); /* set default value */ if (utils_str_equal("", ui_prefs.custom_date_format)) { g_free(ui_prefs.custom_date_format); ui_prefs.custom_date_format = g_strdup("%d.%m.%Y"); } if (utils_str_equal(_("dd.mm.yyyy"), date_style)) format = "%d.%m.%Y"; else if (utils_str_equal(_("mm.dd.yyyy"), date_style)) format = "%m.%d.%Y"; else if (utils_str_equal(_("yyyy/mm/dd"), date_style)) format = "%Y/%m/%d"; else if (utils_str_equal(_("dd.mm.yyyy hh:mm:ss"), date_style)) format = "%d.%m.%Y %H:%M:%S"; else if (utils_str_equal(_("mm.dd.yyyy hh:mm:ss"), date_style)) format = "%m.%d.%Y %H:%M:%S"; else if (utils_str_equal(_("yyyy/mm/dd hh:mm:ss"), date_style)) format = "%Y/%m/%d %H:%M:%S"; else if (utils_str_equal(_("_Use Custom Date Format"), date_style)) format = ui_prefs.custom_date_format; else { gchar *str = dialogs_show_input(_("Custom Date Format"), GTK_WINDOW(main_widgets.window), _("Enter here a custom date and time format. " "For a list of available conversion specifiers see https://docs.gtk.org/glib/method.DateTime.format.html."), ui_prefs.custom_date_format); if (str) SETPTR(ui_prefs.custom_date_format, str); return; } time_str = utils_get_date_time(format, NULL); if (time_str != NULL) { sci_start_undo_action(doc->editor->sci); sci_insert_text(doc->editor->sci, pos, time_str); sci_goto_pos(doc->editor->sci, pos + strlen(time_str), FALSE); sci_end_undo_action(doc->editor->sci); g_free(time_str); } else { utils_beep(); ui_set_statusbar(TRUE, _("Date format string could not be converted (possibly too long).")); } } static void on_popup_insert_date_activate(GtkMenuItem *menuitem, gpointer user_data) { insert_date(document_get_current(), editor_info.click_pos, user_data); } static void on_menu_insert_date_activate(GtkMenuItem *menuitem, gpointer user_data) { insert_date(document_get_current(), -1, user_data); } static void insert_date_items(GtkMenu *me, GtkMenu *mp, gchar *label) { GtkWidget *item; item = gtk_menu_item_new_with_mnemonic(label); gtk_container_add(GTK_CONTAINER(me), item); gtk_widget_show(item); g_signal_connect(item, "activate", G_CALLBACK(on_menu_insert_date_activate), label); item = gtk_menu_item_new_with_mnemonic(label); gtk_container_add(GTK_CONTAINER(mp), item); gtk_widget_show(item); g_signal_connect(item, "activate", G_CALLBACK(on_popup_insert_date_activate), label); } void ui_create_insert_date_menu_items(void) { GtkMenu *menu_edit = GTK_MENU(ui_lookup_widget(main_widgets.window, "insert_date1_menu")); GtkMenu *menu_popup = GTK_MENU(ui_lookup_widget(main_widgets.editor_menu, "insert_date2_menu")); GtkWidget *item; gchar *str; insert_date_items(menu_edit, menu_popup, _("dd.mm.yyyy")); insert_date_items(menu_edit, menu_popup, _("mm.dd.yyyy")); insert_date_items(menu_edit, menu_popup, _("yyyy/mm/dd")); item = gtk_separator_menu_item_new(); gtk_container_add(GTK_CONTAINER(menu_edit), item); gtk_widget_show(item); item = gtk_separator_menu_item_new(); gtk_container_add(GTK_CONTAINER(menu_popup), item); gtk_widget_show(item); insert_date_items(menu_edit, menu_popup, _("dd.mm.yyyy hh:mm:ss")); insert_date_items(menu_edit, menu_popup, _("mm.dd.yyyy hh:mm:ss")); insert_date_items(menu_edit, menu_popup, _("yyyy/mm/dd hh:mm:ss")); item = gtk_separator_menu_item_new(); gtk_container_add(GTK_CONTAINER(menu_edit), item); gtk_widget_show(item); item = gtk_separator_menu_item_new(); gtk_container_add(GTK_CONTAINER(menu_popup), item); gtk_widget_show(item); str = _("_Use Custom Date Format"); item = gtk_menu_item_new_with_mnemonic(str); gtk_container_add(GTK_CONTAINER(menu_edit), item); gtk_widget_show(item); g_signal_connect(item, "activate", G_CALLBACK(on_menu_insert_date_activate), str); ui_hookup_widget(main_widgets.window, item, "insert_date_custom1"); item = gtk_menu_item_new_with_mnemonic(str); gtk_container_add(GTK_CONTAINER(menu_popup), item); gtk_widget_show(item); g_signal_connect(item, "activate", G_CALLBACK(on_popup_insert_date_activate), str); ui_hookup_widget(main_widgets.editor_menu, item, "insert_date_custom2"); insert_date_items(menu_edit, menu_popup, _("_Set Custom Date Format")); } void ui_save_buttons_toggle(gboolean enable) { guint i; gboolean dirty_tabs = FALSE; if (ui_prefs.allow_always_save) enable = gtk_notebook_get_n_pages(GTK_NOTEBOOK(main_widgets.notebook)) > 0; ui_widget_set_sensitive(widgets.save_buttons[0], enable); ui_widget_set_sensitive(widgets.save_buttons[1], enable); /* save all menu item and tool button */ for (i = 0; i < documents_array->len; i++) { /* check whether there are files where changes were made and if there are some, * we need the save all button / item */ if (documents[i]->is_valid && documents[i]->changed) { dirty_tabs = TRUE; break; } } ui_widget_set_sensitive(widgets.save_buttons[2], dirty_tabs); ui_widget_set_sensitive(widgets.save_buttons[3], dirty_tabs); } #define add_doc_widget(widget_name) \ g_ptr_array_add(widgets.document_buttons, ui_lookup_widget(main_widgets.window, widget_name)) #define add_doc_toolitem(widget_name) \ g_ptr_array_add(widgets.document_buttons, toolbar_get_action_by_name(widget_name)) static void init_document_widgets(void) { widgets.document_buttons = g_ptr_array_new(); /* Cache the document-sensitive widgets so we don't have to keep looking them up * when using ui_document_buttons_update(). */ add_doc_widget("menu_close1"); add_doc_widget("close_other_documents1"); add_doc_widget("menu_change_font1"); add_doc_widget("menu_close_all1"); add_doc_widget("menu_save1"); add_doc_widget("menu_save_all1"); add_doc_widget("menu_save_as1"); add_doc_widget("menu_count_words1"); add_doc_widget("menu_build1"); add_doc_widget("add_comments1"); add_doc_widget("menu_paste1"); add_doc_widget("menu_undo2"); add_doc_widget("properties1"); add_doc_widget("menu_reload1"); add_doc_widget("menu_document1"); add_doc_widget("menu_choose_color1"); add_doc_widget("menu_color_schemes"); add_doc_widget("menu_markers_margin1"); add_doc_widget("menu_linenumber_margin1"); add_doc_widget("menu_show_white_space1"); add_doc_widget("menu_show_line_endings1"); add_doc_widget("menu_show_indentation_guides1"); add_doc_widget("menu_zoom_in1"); add_doc_widget("menu_zoom_out1"); add_doc_widget("normal_size1"); add_doc_widget("treeview6"); add_doc_widget("print1"); add_doc_widget("menu_reload_as1"); add_doc_widget("menu_select_all1"); add_doc_widget("insert_date1"); add_doc_widget("insert_alternative_white_space1"); add_doc_widget("menu_format1"); add_doc_widget("commands2"); add_doc_widget("menu_open_selected_file1"); add_doc_widget("page_setup1"); add_doc_widget("find1"); add_doc_widget("find_next1"); add_doc_widget("find_previous1"); add_doc_widget("go_to_next_marker1"); add_doc_widget("go_to_previous_marker1"); add_doc_widget("replace1"); add_doc_widget("find_nextsel1"); add_doc_widget("find_prevsel1"); add_doc_widget("find_usage1"); add_doc_widget("find_document_usage1"); add_doc_widget("mark_all1"); add_doc_widget("go_to_line1"); add_doc_widget("goto_tag_definition1"); add_doc_widget("goto_tag_declaration1"); add_doc_widget("reset_indentation1"); add_doc_toolitem("Close"); add_doc_toolitem("CloseAll"); add_doc_toolitem("Search"); add_doc_toolitem("SearchEntry"); add_doc_toolitem("ZoomIn"); add_doc_toolitem("ZoomOut"); add_doc_toolitem("Indent"); add_doc_toolitem("UnIndent"); add_doc_toolitem("Cut"); add_doc_toolitem("Copy"); add_doc_toolitem("Paste"); add_doc_toolitem("Delete"); add_doc_toolitem("Save"); add_doc_toolitem("SaveAs"); add_doc_toolitem("SaveAll"); add_doc_toolitem("Compile"); add_doc_toolitem("Run"); add_doc_toolitem("Reload"); add_doc_toolitem("Color"); add_doc_toolitem("Goto"); add_doc_toolitem("GotoEntry"); add_doc_toolitem("Replace"); add_doc_toolitem("Print"); } void ui_document_buttons_update(void) { guint i; gboolean enable = gtk_notebook_get_n_pages(GTK_NOTEBOOK(main_widgets.notebook)) > 0; for (i = 0; i < widgets.document_buttons->len; i++) { GtkWidget *widget = g_ptr_array_index(widgets.document_buttons, i); if (GTK_IS_ACTION(widget)) gtk_action_set_sensitive(GTK_ACTION(widget), enable); else ui_widget_set_sensitive(widget, enable); } } static void on_doc_sensitive_widget_destroy(GtkWidget *widget, G_GNUC_UNUSED gpointer user_data) { g_ptr_array_remove_fast(widgets.document_buttons, widget); } /** Adds a widget to the list of widgets that should be set sensitive/insensitive * when some documents are present/no documents are open. * It will be removed when the widget is destroyed. * @param widget The widget to add. * * @since 0.15 **/ GEANY_API_SYMBOL void ui_add_document_sensitive(GtkWidget *widget) { gboolean enable = gtk_notebook_get_n_pages(GTK_NOTEBOOK(main_widgets.notebook)) > 0; ui_widget_set_sensitive(widget, enable); g_ptr_array_add(widgets.document_buttons, widget); g_signal_connect(widget, "destroy", G_CALLBACK(on_doc_sensitive_widget_destroy), NULL); } void ui_widget_show_hide(GtkWidget *widget, gboolean show) { if (show) { gtk_widget_show(widget); } else { gtk_widget_hide(widget); } } void ui_sidebar_show_hide(void) { GtkWidget *widget; /* check that there are no other notebook pages before hiding the sidebar completely * other pages could be e.g. the file browser plugin */ if (! interface_prefs.sidebar_openfiles_visible && ! interface_prefs.sidebar_symbol_visible && gtk_notebook_get_n_pages(GTK_NOTEBOOK(main_widgets.sidebar_notebook)) <= 2) { ui_prefs.sidebar_visible = FALSE; } widget = ui_lookup_widget(main_widgets.window, "menu_show_sidebar1"); if (ui_prefs.sidebar_visible != gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget))) { ignore_callback = TRUE; gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(widget), ui_prefs.sidebar_visible); ignore_callback = FALSE; } ui_widget_show_hide(main_widgets.sidebar_notebook, ui_prefs.sidebar_visible); ui_widget_show_hide(gtk_notebook_get_nth_page( GTK_NOTEBOOK(main_widgets.sidebar_notebook), 0), interface_prefs.sidebar_symbol_visible); ui_widget_show_hide(gtk_notebook_get_nth_page( GTK_NOTEBOOK(main_widgets.sidebar_notebook), 1), interface_prefs.sidebar_openfiles_visible); } void ui_document_show_hide(GeanyDocument *doc) { const gchar *widget_name; GtkWidget *item; const GeanyIndentPrefs *iprefs; g_return_if_fail(doc == NULL || doc->is_valid); if (doc == NULL) doc = document_get_current(); if (doc == NULL) return; ignore_callback = TRUE; gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM(ui_lookup_widget(main_widgets.window, "menu_line_wrapping1")), doc->editor->line_wrapping); gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM(ui_lookup_widget(main_widgets.window, "line_breaking1")), doc->editor->line_breaking); iprefs = editor_get_indent_prefs(doc->editor); item = ui_lookup_widget(main_widgets.window, "menu_use_auto_indentation1"); gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), doc->editor->auto_indent); switch (iprefs->type) { case GEANY_INDENT_TYPE_SPACES: widget_name = "spaces1"; break; case GEANY_INDENT_TYPE_TABS: widget_name = "tabs1"; break; case GEANY_INDENT_TYPE_BOTH: default: widget_name = "tabs_and_spaces1"; break; } item = ui_lookup_widget(main_widgets.window, widget_name); gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), TRUE); if (iprefs->width >= 1 && iprefs->width <= 8) { gchar *name; name = g_strdup_printf("indent_width_%d", iprefs->width); item = ui_lookup_widget(main_widgets.window, name); gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), TRUE); g_free(name); } gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM(ui_lookup_widget(main_widgets.window, "set_file_readonly1")), doc->readonly); item = ui_lookup_widget(main_widgets.window, "menu_write_unicode_bom1"); gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), doc->has_bom); ui_widget_set_sensitive(item, encodings_is_unicode_charset(doc->encoding)); switch (sci_get_eol_mode(doc->editor->sci)) { case SC_EOL_CR: widget_name = "cr"; break; case SC_EOL_LF: widget_name = "lf"; break; default: widget_name = "crlf"; break; } gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM(ui_lookup_widget(main_widgets.window, widget_name)), TRUE); encodings_select_radio_item(doc->encoding); filetypes_select_radio_item(doc->file_type); ignore_callback = FALSE; } void ui_set_search_entry_background(GtkWidget *widget, gboolean success) { gtk_widget_set_name(widget, success ? NULL : "geany-search-entry-no-match"); } static void recent_create_menu(GeanyRecentFiles *grf) { guint i, len; len = MIN(file_prefs.mru_length, g_queue_get_length(grf->recent_queue)); for (i = 0; i < len; i++) { /* create menu item for the recent files menu in the menu bar */ const gchar *filename = g_queue_peek_nth(grf->recent_queue, i); GtkWidget *tmp = gtk_menu_item_new_with_label(filename); gtk_widget_show(tmp); gtk_container_add(GTK_CONTAINER(grf->menubar), tmp); g_signal_connect(tmp, "activate", G_CALLBACK(grf->activate_cb), NULL); /* create menu item for the recent files menu in the toolbar */ if (grf->toolbar != NULL) { tmp = gtk_menu_item_new_with_label(filename); gtk_widget_show(tmp); gtk_container_add(GTK_CONTAINER(grf->toolbar), tmp); g_signal_connect(tmp, "activate", G_CALLBACK(grf->activate_cb), NULL); } } } static GeanyRecentFiles *recent_get_recent_files(void) { static GeanyRecentFiles grf = { RECENT_FILE_FILE, NULL, NULL, NULL, NULL }; if (G_UNLIKELY(grf.recent_queue == NULL)) { grf.recent_queue = ui_prefs.recent_queue; grf.menubar = ui_widgets.recent_files_menu_menubar; grf.toolbar = geany_menu_button_action_get_menu(GEANY_MENU_BUTTON_ACTION( toolbar_get_action_by_name("Open"))); grf.activate_cb = recent_file_activate_cb; } return &grf; } static GeanyRecentFiles *recent_get_recent_projects(void) { static GeanyRecentFiles grf = { RECENT_FILE_PROJECT, NULL, NULL, NULL, NULL }; if (G_UNLIKELY(grf.recent_queue == NULL)) { grf.recent_queue = ui_prefs.recent_projects_queue; grf.menubar = ui_widgets.recent_projects_menu_menubar; grf.toolbar = NULL; grf.activate_cb = recent_project_activate_cb; } return &grf; } void ui_create_recent_menus(void) { recent_create_menu(recent_get_recent_files()); recent_create_menu(recent_get_recent_projects()); } static void recent_file_activate_cb(GtkMenuItem *menuitem, G_GNUC_UNUSED gpointer user_data) { gchar *utf8_filename = ui_menu_item_get_text(menuitem); gchar *locale_filename = utils_get_locale_from_utf8(utf8_filename); if (document_open_file(locale_filename, FALSE, NULL, NULL) != NULL) recent_file_loaded(utf8_filename, recent_get_recent_files()); g_free(locale_filename); g_free(utf8_filename); } static void recent_project_activate_cb(GtkMenuItem *menuitem, G_GNUC_UNUSED gpointer user_data) { gchar *utf8_filename = ui_menu_item_get_text(menuitem); gchar *locale_filename = utils_get_locale_from_utf8(utf8_filename); if (app->project && !project_close(FALSE)) {} else if (project_load_file_with_session(locale_filename)) recent_file_loaded(utf8_filename, recent_get_recent_projects()); g_free(locale_filename); g_free(utf8_filename); } static void add_recent_file(const gchar *utf8_filename, GeanyRecentFiles *grf, const GtkRecentData *rdata) { if (g_queue_find_custom(grf->recent_queue, utf8_filename, (GCompareFunc) strcmp) == NULL) { if (grf->type == RECENT_FILE_FILE && rdata) { GtkRecentManager *manager = gtk_recent_manager_get_default(); gchar *uri = g_filename_to_uri(utf8_filename, NULL, NULL); if (uri != NULL) { gtk_recent_manager_add_full(manager, uri, rdata); g_free(uri); } } g_queue_push_head(grf->recent_queue, g_strdup(utf8_filename)); if (g_queue_get_length(grf->recent_queue) > file_prefs.mru_length) { g_free(g_queue_pop_tail(grf->recent_queue)); } update_recent_menu(grf); } /* filename already in recent list */ else recent_file_loaded(utf8_filename, grf); } void ui_add_recent_document(GeanyDocument *doc) { /* what are the groups for actually? */ static const gchar *groups[2] = { "geany", NULL }; GtkRecentData rdata; /* Prepare the data for gtk_recent_manager_add_full() */ rdata.display_name = NULL; rdata.description = NULL; rdata.mime_type = doc->file_type->mime_type; /* if we ain't got no mime-type, fallback to plain text */ if (! rdata.mime_type) rdata.mime_type = (gchar *) "text/plain"; rdata.app_name = (gchar *) "geany"; rdata.app_exec = (gchar *) "geany %u"; rdata.groups = (gchar **) groups; rdata.is_private = FALSE; add_recent_file(doc->file_name, recent_get_recent_files(), &rdata); } void ui_add_recent_project_file(const gchar *utf8_filename) { add_recent_file(utf8_filename, recent_get_recent_projects(), NULL); } /* Returns: newly allocated string with the UTF-8 menu text. */ gchar *ui_menu_item_get_text(GtkMenuItem *menu_item) { const gchar *text = NULL; if (gtk_bin_get_child(GTK_BIN(menu_item))) { GtkWidget *child = gtk_bin_get_child(GTK_BIN(menu_item)); if (GTK_IS_LABEL(child)) text = gtk_label_get_text(GTK_LABEL(child)); } /* GTK owns text so it's much safer to return a copy of it in case the memory is reallocated */ return g_strdup(text); } static gint find_recent_file_item(gconstpointer list_data, gconstpointer user_data) { gchar *menu_text = ui_menu_item_get_text(GTK_MENU_ITEM(list_data)); gint result; if (utils_str_equal(menu_text, user_data)) result = 0; else result = 1; g_free(menu_text); return result; } /* update the project menu item's sensitivity */ void ui_update_recent_project_menu(void) { GeanyRecentFiles *grf = recent_get_recent_projects(); GList *children, *item; /* only need to update the menubar menu, the project doesn't have a toolbar item */ children = gtk_container_get_children(GTK_CONTAINER(grf->menubar)); for (item = children; item; item = item->next) { gboolean sensitive = TRUE; if (app->project) { const gchar *filename = gtk_menu_item_get_label(item->data); sensitive = g_strcmp0(app->project->file_name, filename) != 0; } gtk_widget_set_sensitive(item->data, sensitive); } g_list_free(children); } /* Use instead of gtk_menu_reorder_child() to update the menubar properly on OS X */ static void menu_reorder_child(GtkMenu *menu, GtkWidget *child, gint position) { gtk_menu_reorder_child(menu, child, position); #ifdef MAC_INTEGRATION /* On OS X GtkMenuBar is kept in sync with the native OS X menubar using * signals. Unfortunately gtk_menu_reorder_child() doesn't emit anything * so we have to update the OS X menubar manually. */ gtkosx_application_sync_menubar(gtkosx_application_get()); #endif } static void add_recent_file_menu_item(const gchar *utf8_filename, GeanyRecentFiles *grf, GtkWidget *menu) { GtkWidget *child = gtk_menu_item_new_with_label(utf8_filename); gtk_widget_show(child); if (menu != grf->toolbar) gtk_menu_shell_prepend(GTK_MENU_SHELL(menu), child); else { /* this is a bit ugly, but we need to use gtk_container_add(). Using * gtk_menu_shell_prepend() doesn't emit GtkContainer's "add" signal * which we need in GeanyMenubuttonAction */ gtk_container_add(GTK_CONTAINER(menu), child); menu_reorder_child(GTK_MENU(menu), child, 0); } g_signal_connect(child, "activate", G_CALLBACK(grf->activate_cb), NULL); } static void recent_file_loaded(const gchar *utf8_filename, GeanyRecentFiles *grf) { GList *item; GtkWidget *parents[] = { grf->menubar, grf->toolbar }; guint i; /* first reorder the queue */ item = g_queue_find_custom(grf->recent_queue, utf8_filename, (GCompareFunc) strcmp); g_return_if_fail(item != NULL); g_queue_unlink(grf->recent_queue, item); g_queue_push_head_link(grf->recent_queue, item); for (i = 0; i < G_N_ELEMENTS(parents); i++) { GList *children; if (! parents[i]) continue; children = gtk_container_get_children(GTK_CONTAINER(parents[i])); item = g_list_find_custom(children, utf8_filename, (GCompareFunc) find_recent_file_item); /* either reorder or prepend a new one */ if (item) menu_reorder_child(GTK_MENU(parents[i]), item->data, 0); else add_recent_file_menu_item(utf8_filename, grf, parents[i]); g_list_free(children); } if (grf->type == RECENT_FILE_PROJECT) ui_update_recent_project_menu(); } static void update_recent_menu(GeanyRecentFiles *grf) { gchar *filename; GtkWidget *parents[] = { grf->menubar, grf->toolbar }; guint i; filename = g_queue_peek_head(grf->recent_queue); for (i = 0; i < G_N_ELEMENTS(parents); i++) { GList *children; if (! parents[i]) continue; /* clean the MRU list before adding an item */ children = gtk_container_get_children(GTK_CONTAINER(parents[i])); if (g_list_length(children) > file_prefs.mru_length - 1) { GList *item = g_list_nth(children, file_prefs.mru_length - 1); while (item != NULL) { if (GTK_IS_MENU_ITEM(item->data)) gtk_widget_destroy(GTK_WIDGET(item->data)); item = g_list_next(item); } } g_list_free(children); /* create the new item */ add_recent_file_menu_item(filename, grf, parents[i]); } if (grf->type == RECENT_FILE_PROJECT) ui_update_recent_project_menu(); } void ui_toggle_editor_features(GeanyUIEditorFeatures feature) { guint i; foreach_document (i) { GeanyDocument *doc = documents[i]; switch (feature) { case GEANY_EDITOR_SHOW_MARKERS_MARGIN: sci_set_symbol_margin(doc->editor->sci, editor_prefs.show_markers_margin); break; case GEANY_EDITOR_SHOW_LINE_NUMBERS: sci_set_line_numbers(doc->editor->sci, editor_prefs.show_linenumber_margin); break; case GEANY_EDITOR_SHOW_WHITE_SPACE: sci_set_visible_white_spaces(doc->editor->sci, editor_prefs.show_white_space); break; case GEANY_EDITOR_SHOW_LINE_ENDINGS: sci_set_visible_eols(doc->editor->sci, editor_prefs.show_line_endings); break; case GEANY_EDITOR_SHOW_INDENTATION_GUIDES: editor_set_indentation_guides(doc->editor); break; } } } void ui_update_view_editor_menu_items(void) { ignore_callback = TRUE; gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(ui_lookup_widget(main_widgets.window, "menu_markers_margin1")), editor_prefs.show_markers_margin); gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(ui_lookup_widget(main_widgets.window, "menu_linenumber_margin1")), editor_prefs.show_linenumber_margin); gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(ui_lookup_widget(main_widgets.window, "menu_show_white_space1")), editor_prefs.show_white_space); gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(ui_lookup_widget(main_widgets.window, "menu_show_line_endings1")), editor_prefs.show_line_endings); gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(ui_lookup_widget(main_widgets.window, "menu_show_indentation_guides1")), editor_prefs.show_indent_guide); ignore_callback = FALSE; } /** Creates a GNOME HIG-style frame (with no border and indented child alignment). * @param label_text The label text. * @param alignment An address to store the alignment widget pointer. * * @return @transfer{floating} The frame widget, setting the alignment container for * packing child widgets. * * @deprecated 1.29: Use GTK API directly **/ GEANY_API_SYMBOL GtkWidget *ui_frame_new_with_alignment(const gchar *label_text, GtkWidget **alignment) { GtkWidget *label, *align; GtkWidget *frame = gtk_frame_new(NULL); gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_NONE); align = gtk_alignment_new(0.5, 0.5, 1, 1); gtk_container_add(GTK_CONTAINER(frame), align); gtk_alignment_set_padding(GTK_ALIGNMENT(align), 0, 0, 12, 0); label = ui_label_new_bold(label_text); gtk_frame_set_label_widget(GTK_FRAME(frame), label); *alignment = align; return frame; } /** Makes a fixed border for dialogs without increasing the button box border. * @param dialog The parent container for the @c GtkVBox. * * @return @transfer{none} The packed @c GtkVBox. */ GEANY_API_SYMBOL GtkWidget *ui_dialog_vbox_new(GtkDialog *dialog) { GtkWidget *vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 12); /* need child vbox to set a separate border. */ gtk_container_set_border_width(GTK_CONTAINER(vbox), 6); gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), vbox, TRUE, TRUE, 0); return vbox; } /* Reorders a dialog's buttons * @param dialog A dialog * @param response First response ID to reorder * @param ... more response IDs, terminated by -1 * * Like gtk_dialog_set_alternative_button_order(), but reorders the default * buttons layout, not the alternative one. This is useful if you e.g. added a * button to a dialog which already had some and need yours not to be on the * end. */ /* Heavily based on gtk_dialog_set_alternative_button_order(). * This relies on the action area to be a GtkBox, but although not documented * the API expose it to be a GtkHButtonBox though GtkBuilder, so it should be * fine */ void ui_dialog_set_primary_button_order(GtkDialog *dialog, gint response, ...) { va_list ap; GtkWidget *action_area = gtk_dialog_get_action_area(dialog); gint position; va_start(ap, response); for (position = 0; response != -1; position++) { GtkWidget *child = gtk_dialog_get_widget_for_response(dialog, response); if (child) gtk_box_reorder_child(GTK_BOX(action_area), child, position); else g_warning("%s: no child button with response id %d.", G_STRFUNC, response); response = va_arg(ap, gint); } va_end(ap); } /** Creates a @c GtkButton with custom text and a stock image similar to * @c gtk_button_new_from_stock(). * @param stock_id A @c GTK_STOCK_NAME string. * @param text Button label text, can include mnemonics. * * @return @transfer{floating} The new @c GtkButton. */ GEANY_API_SYMBOL GtkWidget *ui_button_new_with_image(const gchar *stock_id, const gchar *text) { GtkWidget *image, *button; button = gtk_button_new_with_mnemonic(text); gtk_widget_show(button); image = gtk_image_new_from_stock(stock_id, GTK_ICON_SIZE_BUTTON); gtk_button_set_image(GTK_BUTTON(button), image); /* note: image is shown by gtk */ return button; } /** Creates a @c GtkImageMenuItem with a stock image and a custom label. * @param stock_id Stock image ID, e.g. @c GTK_STOCK_OPEN. * @param label Menu item label, can include mnemonics. * @return @transfer{floating} The new @c GtkImageMenuItem. * * @since 0.16 */ GEANY_API_SYMBOL GtkWidget * ui_image_menu_item_new(const gchar *stock_id, const gchar *label) { GtkWidget *item = gtk_image_menu_item_new_with_mnemonic(label); GtkWidget *image = gtk_image_new_from_stock(stock_id, GTK_ICON_SIZE_MENU); gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), image); gtk_widget_show(image); return item; } static void entry_clear_icon_release_cb(GtkEntry *entry, gint icon_pos, GdkEvent *event, gpointer data) { if (event->button.button == 1 && icon_pos == 1) { gtk_entry_set_text(entry, ""); gtk_widget_grab_focus(GTK_WIDGET(entry)); } } /** Adds a small clear icon to the right end of the passed @a entry. * A callback to clear the contents of the GtkEntry is automatically added. * * @param entry The GtkEntry object to which the icon should be attached. * * @since 0.16 */ GEANY_API_SYMBOL void ui_entry_add_clear_icon(GtkEntry *entry) { g_object_set(entry, "secondary-icon-stock", GTK_STOCK_CLEAR, "secondary-icon-activatable", TRUE, NULL); g_signal_connect(entry, "icon-release", G_CALLBACK(entry_clear_icon_release_cb), NULL); } /* Adds a :activate-backwards signal emitted by default when Return is pressed */ void ui_entry_add_activate_backward_signal(GtkEntry *entry) { static gboolean installed = FALSE; g_return_if_fail(GTK_IS_ENTRY(entry)); if (G_UNLIKELY(! installed)) { GtkBindingSet *binding_set; installed = TRUE; /* try to handle the unexpected case where GTK would already have installed the signal */ if (g_signal_lookup("activate-backward", G_TYPE_FROM_INSTANCE(entry))) { g_warning("Signal GtkEntry:activate-backward is unexpectedly already installed"); return; } g_signal_new("activate-backward", G_TYPE_FROM_INSTANCE(entry), G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); binding_set = gtk_binding_set_by_class(GTK_ENTRY_GET_CLASS(entry)); gtk_binding_entry_add_signal(binding_set, GDK_KEY_Return, GDK_SHIFT_MASK, "activate-backward", 0); } } static void add_to_size_group(GtkWidget *widget, gpointer size_group) { g_return_if_fail(GTK_IS_SIZE_GROUP(size_group)); gtk_size_group_add_widget(GTK_SIZE_GROUP(size_group), widget); } /* Copies the spacing and layout of the master GtkHButtonBox and synchronises * the width of each button box's children. * Should be called after all child widgets have been packed. */ void ui_hbutton_box_copy_layout(GtkButtonBox *master, GtkButtonBox *copy) { GtkSizeGroup *size_group; gtk_box_set_spacing(GTK_BOX(copy), 10); gtk_button_box_set_layout(copy, gtk_button_box_get_layout(master)); /* now we need to put the widest widget from each button box in a size group, * but we don't know the width before they are drawn, and for different label * translations the widest widget can vary, so we just add all widgets. */ size_group = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); gtk_container_foreach(GTK_CONTAINER(master), add_to_size_group, size_group); gtk_container_foreach(GTK_CONTAINER(copy), add_to_size_group, size_group); g_object_unref(size_group); } static gboolean tree_model_find_text(GtkTreeModel *model, GtkTreeIter *iter, gint column, const gchar *text) { gchar *combo_text; gboolean found = FALSE; if (gtk_tree_model_get_iter_first(model, iter)) { do { gtk_tree_model_get(model, iter, 0, &combo_text, -1); found = utils_str_equal(combo_text, text); g_free(combo_text); if (found) return TRUE; } while (gtk_tree_model_iter_next(model, iter)); } return FALSE; } /** Prepends @a text to the drop down list, removing a duplicate element in * the list if found. Also ensures there are <= @a history_len elements. * @param combo_entry . * @param text @nullable Text to add, or @c NULL for current entry text. * @param history_len Max number of items, or @c 0 for default. */ GEANY_API_SYMBOL void ui_combo_box_add_to_history(GtkComboBoxText *combo_entry, const gchar *text, gint history_len) { GtkComboBox *combo = GTK_COMBO_BOX(combo_entry); GtkTreeModel *model; GtkTreeIter iter; GtkTreePath *path; if (history_len <= 0) history_len = 10; if (!text) text = gtk_entry_get_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN(combo)))); model = gtk_combo_box_get_model(combo); if (tree_model_find_text(model, &iter, 0, text)) { gtk_list_store_remove(GTK_LIST_STORE(model), &iter); } gtk_combo_box_text_prepend_text(combo_entry, text); /* limit history */ path = gtk_tree_path_new_from_indices(history_len, -1); if (gtk_tree_model_get_iter(model, &iter, path)) { gtk_list_store_remove(GTK_LIST_STORE(model), &iter); } gtk_tree_path_free(path); } /* Same as gtk_combo_box_text_prepend_text(), except that text is only prepended if it not already * exists in the combo's model. */ void ui_combo_box_prepend_text_once(GtkComboBoxText *combo, const gchar *text) { GtkTreeModel *model; GtkTreeIter iter; model = gtk_combo_box_get_model(GTK_COMBO_BOX(combo)); if (tree_model_find_text(model, &iter, 0, text)) return; /* don't prepend duplicate */ gtk_combo_box_text_prepend_text(combo, text); } /* Changes the color of the notebook tab text and open files items according to * document status. */ void ui_update_tab_status(GeanyDocument *doc) { gtk_widget_set_name(doc->priv->tab_label, document_get_status_widget_class(doc)); sidebar_openfiles_update(doc); } static gboolean tree_model_iter_get_next(GtkTreeModel *model, GtkTreeIter *iter, gboolean down) { GtkTreePath *path; gboolean result; if (down) return gtk_tree_model_iter_next(model, iter); path = gtk_tree_model_get_path(model, iter); result = gtk_tree_path_prev(path) && gtk_tree_model_get_iter(model, iter, path); gtk_tree_path_free(path); return result; } /* note: the while loop might be more efficient when searching upwards if it * used tree paths instead of tree iters, but in practice it probably doesn't matter much. */ static gboolean tree_view_find(GtkTreeView *treeview, TVMatchCallback cb, gboolean down) { GtkTreeSelection *treesel; GtkTreeIter iter; GtkTreeModel *model; treesel = gtk_tree_view_get_selection(treeview); if (gtk_tree_selection_get_selected(treesel, &model, &iter)) { /* get the next selected item */ if (! tree_model_iter_get_next(model, &iter, down)) return FALSE; /* no more items */ } else /* no selection */ { if (! gtk_tree_model_get_iter_first(model, &iter)) return TRUE; /* no items */ } while (TRUE) { gtk_tree_selection_select_iter(treesel, &iter); if (cb(FALSE)) break; /* found next message */ if (! tree_model_iter_get_next(model, &iter, down)) return FALSE; /* no more items */ } /* scroll item in view */ if (ui_prefs.msgwindow_visible) { GtkTreePath *path = gtk_tree_model_get_path( gtk_tree_view_get_model(treeview), &iter); gtk_tree_view_scroll_to_cell(treeview, path, NULL, TRUE, 0.5, 0.5); gtk_tree_path_free(path); } return TRUE; } /* Returns FALSE if the treeview has items but no matching next item. */ gboolean ui_tree_view_find_next(GtkTreeView *treeview, TVMatchCallback cb) { return tree_view_find(treeview, cb, TRUE); } /* Returns FALSE if the treeview has items but no matching next item. */ gboolean ui_tree_view_find_previous(GtkTreeView *treeview, TVMatchCallback cb) { return tree_view_find(treeview, cb, FALSE); } /* Shamelessly stolen from GTK */ static gboolean ui_tree_view_query_tooltip_cb(GtkWidget *widget, gint x, gint y, gboolean keyboard_tip, GtkTooltip *tooltip, gpointer data) { GValue value = { 0 }; GValue transformed = { 0 }; GtkTreeIter iter; GtkTreePath *path; GtkTreeModel *model; GtkTreeView *tree_view = GTK_TREE_VIEW(widget); gint column = GPOINTER_TO_INT(data); gboolean tootlip_set = FALSE; if (! gtk_tree_view_get_tooltip_context(tree_view, &x, &y, keyboard_tip, &model, &path, &iter)) return FALSE; gtk_tree_model_get_value(model, &iter, column, &value); g_value_init(&transformed, G_TYPE_STRING); if (g_value_transform(&value, &transformed) && g_value_get_string(&transformed)) { gtk_tooltip_set_text(tooltip, g_value_get_string(&transformed)); gtk_tree_view_set_tooltip_row(tree_view, tooltip, path); tootlip_set = TRUE; } g_value_unset(&transformed); g_value_unset(&value); gtk_tree_path_free(path); return tootlip_set; } /** Adds text tooltips to a tree view. * * This is similar to gtk_tree_view_set_tooltip_column() but considers the column contents to be * text, not markup -- it uses gtk_tooltip_set_text() rather than gtk_tooltip_set_markup() to set * the tooltip's value. * * @warning Unlike gtk_tree_view_set_tooltip_column() you currently cannot change or remove the * tooltip column after it has been added. Trying to do so will probably give funky results. * * @param tree_view The tree view * @param column The column to get the tooltip from * * @since 1.25 (API 223) */ /* Note: @p column is int and not uint both to match gtk_tree_view_set_tooltip_column() signature * and to allow future support of -1 to unset if ever wanted */ GEANY_API_SYMBOL void ui_tree_view_set_tooltip_text_column(GtkTreeView *tree_view, gint column) { g_return_if_fail(column >= 0); g_return_if_fail(GTK_IS_TREE_VIEW(tree_view)); g_signal_connect(tree_view, "query-tooltip", G_CALLBACK(ui_tree_view_query_tooltip_cb), GINT_TO_POINTER(column)); gtk_widget_set_has_tooltip(GTK_WIDGET(tree_view), TRUE); } /** * Modifies the font of a widget using gtk_widget_modify_font(). * * @param widget The widget. * @param str The font name as expected by pango_font_description_from_string(). */ GEANY_API_SYMBOL void ui_widget_modify_font_from_string(GtkWidget *widget, const gchar *str) { PangoFontDescription *pfd; pfd = pango_font_description_from_string(str); gtk_widget_modify_font(widget, pfd); pango_font_description_free(pfd); } /** Creates a @c GtkHBox with @a entry packed into it and an open button which runs a * file chooser, replacing entry text (if successful) with the path returned from the * @c GtkFileChooser. * @note @a entry can be the child of an unparented widget, such as @c GtkComboBoxEntry. * @param title @nullable The file chooser dialog title, or @c NULL. * @param action The mode of the file chooser. * @param entry Can be an unpacked @c GtkEntry, or the child of an unpacked widget, * such as @c GtkComboBoxEntry. * * @return @transfer{floating} The @c GtkHBox. */ /* @see ui_setup_open_button_callback(). */ GEANY_API_SYMBOL GtkWidget *ui_path_box_new(const gchar *title, GtkFileChooserAction action, GtkEntry *entry) { GtkWidget *vbox, *dirbtn, *openimg, *hbox, *path_entry, *parent, *next_parent; hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6); path_entry = GTK_WIDGET(entry); /* prevent path_entry being vertically stretched to the height of dirbtn */ vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); parent = path_entry; while ((next_parent = gtk_widget_get_parent(parent)) != NULL) parent = next_parent; gtk_box_pack_start(GTK_BOX(vbox), parent, TRUE, FALSE, 0); dirbtn = gtk_button_new(); openimg = gtk_image_new_from_stock(GTK_STOCK_OPEN, GTK_ICON_SIZE_BUTTON); gtk_container_add(GTK_CONTAINER(dirbtn), openimg); ui_setup_open_button_callback(dirbtn, title, action, entry); gtk_box_pack_end(GTK_BOX(hbox), dirbtn, FALSE, FALSE, 0); gtk_box_pack_end(GTK_BOX(hbox), vbox, TRUE, TRUE, 0); return hbox; } static void ui_path_box_open_clicked(GtkButton *button, gpointer user_data); /* Setup a GtkButton to run a GtkFileChooser, setting entry text if successful. * title can be NULL. * action is the file chooser mode to use. */ void ui_setup_open_button_callback(GtkWidget *open_btn, const gchar *title, GtkFileChooserAction action, GtkEntry *entry) { GtkWidget *path_entry = GTK_WIDGET(entry); if (title) g_object_set_data_full(G_OBJECT(open_btn), "title", g_strdup(title), (GDestroyNotify) g_free); g_object_set_data(G_OBJECT(open_btn), "action", GINT_TO_POINTER(action)); g_signal_connect(open_btn, "clicked", G_CALLBACK(ui_path_box_open_clicked), path_entry); } #ifndef G_OS_WIN32 static gchar *run_file_chooser(const gchar *title, GtkFileChooserAction action, const gchar *utf8_path) { GtkWidget *dialog = gtk_file_chooser_dialog_new(title, GTK_WINDOW(main_widgets.window), action, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_OK, NULL); gchar *locale_path; gchar *ret_path = NULL; gtk_widget_set_name(dialog, "GeanyDialog"); locale_path = utils_get_locale_from_utf8(utf8_path); if (action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER) { if (g_path_is_absolute(locale_path) && g_file_test(locale_path, G_FILE_TEST_IS_DIR)) gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), locale_path); } else if (action == GTK_FILE_CHOOSER_ACTION_OPEN) { if (g_path_is_absolute(locale_path)) gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), locale_path); } g_free(locale_path); if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK) { gchar *dir_locale; dir_locale = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); ret_path = utils_get_utf8_from_locale(dir_locale); g_free(dir_locale); } gtk_widget_destroy(dialog); return ret_path; } #endif gchar *ui_get_project_directory(const gchar *path) { gchar *utf8_path; const gchar *title = _("Select Project Base Path"); #ifdef G_OS_WIN32 utf8_path = win32_show_folder_dialog(ui_widgets.prefs_dialog, title, path); #else utf8_path = run_file_chooser(title, GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, path); #endif return utf8_path; } static void ui_path_box_open_clicked(GtkButton *button, gpointer user_data) { GtkFileChooserAction action = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(button), "action")); GtkEntry *entry = user_data; const gchar *title = g_object_get_data(G_OBJECT(button), "title"); gchar *utf8_path = NULL; /* TODO: extend for other actions */ g_return_if_fail(action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER || action == GTK_FILE_CHOOSER_ACTION_OPEN); if (title == NULL) title = (action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER) ? _("Select Folder") : _("Select File"); if (action == GTK_FILE_CHOOSER_ACTION_OPEN) { #ifdef G_OS_WIN32 utf8_path = win32_show_file_dialog(GTK_WINDOW(ui_widgets.prefs_dialog), title, gtk_entry_get_text(GTK_ENTRY(entry))); #else utf8_path = run_file_chooser(title, action, gtk_entry_get_text(GTK_ENTRY(entry))); #endif } else if (action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER) { gchar *path = g_path_get_dirname(gtk_entry_get_text(GTK_ENTRY(entry))); #ifdef G_OS_WIN32 utf8_path = win32_show_folder_dialog(ui_widgets.prefs_dialog, title, gtk_entry_get_text(GTK_ENTRY(entry))); #else utf8_path = run_file_chooser(title, action, path); #endif g_free(path); } if (utf8_path != NULL) { gtk_entry_set_text(GTK_ENTRY(entry), utf8_path); g_free(utf8_path); } } void ui_statusbar_showhide(gboolean state) { /* handle statusbar visibility */ if (state) { gtk_widget_show(ui_widgets.statusbar); ui_update_statusbar(NULL, -1); } else gtk_widget_hide(ui_widgets.statusbar); } /** Packs all @c GtkWidgets passed after the row argument into a table, using * one widget per cell. The first widget is not expanded as the table grows, * as this is usually a label. * @param table * @param row The row number of the table. */ GEANY_API_SYMBOL void ui_table_add_row(GtkTable *table, gint row, ...) { va_list args; guint i; GtkWidget *widget; va_start(args, row); for (i = 0; (widget = va_arg(args, GtkWidget*), widget != NULL); i++) { gint options = (i == 0) ? GTK_FILL : GTK_EXPAND | GTK_FILL; gtk_table_attach(GTK_TABLE(table), widget, i, i + 1, row, row + 1, options, 0, 0, 0); } va_end(args); } /* comment-out all lines that are not already commented out except sections */ static void comment_conf_files(ScintillaObject *sci) { gint line, line_count; line_count = sci_get_line_count(sci); for (line = 0; line < line_count; line++) { gint pos_start = sci_get_position_from_line(sci, line); gint pos_end = sci_get_line_end_position(sci, line); gint pos; for (pos = pos_start; pos < pos_end; pos++) { gchar c = sci_get_char_at(sci, pos); if (c == '[' || c == '#') break; if (!isspace(c)) { sci_insert_text(sci, pos_start, "#"); break; } } } } static void on_config_file_clicked(GtkWidget *widget, gpointer user_data) { const gchar *file_name = user_data; GeanyFiletype *ft = NULL; if (strstr(file_name, G_DIR_SEPARATOR_S "filetypes.")) ft = filetypes[GEANY_FILETYPES_CONF]; if (g_file_test(file_name, G_FILE_TEST_EXISTS)) document_open_file(file_name, FALSE, ft, NULL); else { gchar *utf8_filename = utils_get_utf8_from_locale(file_name); gchar *global_file; gchar *base_name = NULL; gchar *global_content = NULL; GeanyDocument *doc = NULL; /* get the path inside app->configdir - can contain subdirectories */ if (g_str_has_prefix(file_name, app->configdir)) { gsize len = strlen(app->configdir); if (file_name[len] == G_DIR_SEPARATOR) base_name = g_strdup(file_name + len + 1); } if (!base_name) base_name = g_path_get_basename(file_name); global_file = g_build_filename(app->datadir, base_name, NULL); /* if the requested file doesn't exist in the user's config dir, try loading the file * from the global data directory and use its contents for the newly created file */ if (g_file_test(global_file, G_FILE_TEST_EXISTS)) g_file_get_contents(global_file, &global_content, NULL, NULL); doc = document_new_file(utf8_filename, ft, global_content); if (global_content && doc->file_type->id == GEANY_FILETYPES_CONF) { comment_conf_files(doc->editor->sci); sci_set_current_line(doc->editor->sci, 0); document_set_text_changed(doc, FALSE); sci_empty_undo_buffer(doc->editor->sci); ui_document_show_hide(doc); /* update the document menu */ } utils_free_pointers(4, utf8_filename, base_name, global_file, global_content, NULL); } } static void free_on_closure_notify(gpointer data, GClosure *closure) { g_free(data); } /* @note You should connect to the "document-save" signal yourself to detect * if the user has just saved the config file, reloading it. */ void ui_add_config_file_menu_item(const gchar *real_path, const gchar *label, GtkContainer *parent) { GtkWidget *item; if (!parent) parent = GTK_CONTAINER(widgets.config_files_menu); if (!label) { gchar *base_name; base_name = g_path_get_basename(real_path); item = gtk_menu_item_new_with_label(base_name); g_free(base_name); } else item = gtk_menu_item_new_with_mnemonic(label); gtk_widget_show(item); gtk_container_add(parent, item); g_signal_connect_data(item, "activate", G_CALLBACK(on_config_file_clicked), g_strdup(real_path), free_on_closure_notify, 0); } static gboolean sort_menu(gpointer data) { ui_menu_sort_by_label(GTK_MENU(data)); return FALSE; } static void create_config_files_menu(void) { GtkWidget *menu, *item; widgets.config_files_menu = menu = gtk_menu_new(); item = ui_lookup_widget(main_widgets.window, "configuration_files1"); gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), menu); item = gtk_menu_item_new_with_mnemonic(_("_Filetype Configuration")); gtk_container_add(GTK_CONTAINER(menu), item); ui_widgets.config_files_filetype_menu = gtk_menu_new(); gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), ui_widgets.config_files_filetype_menu); gtk_widget_show(item); /* sort menu after all items added */ g_idle_add(sort_menu, widgets.config_files_menu); } /* adds factory icons with a named icon source using the stock items id */ static void add_stock_icons(const GtkStockItem *items, gsize count) { GtkIconFactory *factory = gtk_icon_factory_new(); GtkIconSource *source = gtk_icon_source_new(); gsize i; for (i = 0; i < count; i++) { GtkIconSet *set = gtk_icon_set_new(); gtk_icon_source_set_icon_name(source, items[i].stock_id); gtk_icon_set_add_source(set, source); gtk_icon_factory_add(factory, items[i].stock_id, set); gtk_icon_set_unref(set); } gtk_icon_source_free(source); gtk_icon_factory_add_default(factory); g_object_unref(factory); } void ui_init_stock_items(void) { GtkStockItem items[] = { { GEANY_STOCK_SAVE_ALL, N_("Save All"), 0, 0, GETTEXT_PACKAGE }, { GEANY_STOCK_CLOSE_ALL, N_("Close All"), 0, 0, GETTEXT_PACKAGE }, { GEANY_STOCK_BUILD, N_("Build"), 0, 0, GETTEXT_PACKAGE } }; gtk_stock_add(items, G_N_ELEMENTS(items)); add_stock_icons(items, G_N_ELEMENTS(items)); } void ui_init_toolbar_widgets(void) { widgets.save_buttons[1] = toolbar_get_widget_by_name("Save"); widgets.save_buttons[3] = toolbar_get_widget_by_name("SaveAll"); widgets.redo_items[2] = toolbar_get_widget_by_name("Redo"); widgets.undo_items[2] = toolbar_get_widget_by_name("Undo"); } void ui_swap_sidebar_pos(void) { GtkWidget *pane = ui_lookup_widget(main_widgets.window, "hpaned1"); GtkWidget *left = gtk_paned_get_child1(GTK_PANED(pane)); GtkWidget *right = gtk_paned_get_child2(GTK_PANED(pane)); g_object_ref(left); g_object_ref(right); gtk_container_remove (GTK_CONTAINER (pane), left); gtk_container_remove (GTK_CONTAINER (pane), right); /* only scintilla notebook should expand */ gtk_paned_pack1(GTK_PANED(pane), right, right == main_widgets.notebook, TRUE); gtk_paned_pack2(GTK_PANED(pane), left, left == main_widgets.notebook, TRUE); g_object_unref(left); g_object_unref(right); gtk_paned_set_position(GTK_PANED(pane), gtk_widget_get_allocated_width(pane) - gtk_paned_get_position(GTK_PANED(pane))); } static void init_recent_files(void) { GtkWidget *toolbar_recent_files_menu; /* add recent files to the File menu */ ui_widgets.recent_files_menuitem = ui_lookup_widget(main_widgets.window, "recent_files1"); ui_widgets.recent_files_menu_menubar = gtk_menu_new(); gtk_menu_item_set_submenu(GTK_MENU_ITEM(ui_widgets.recent_files_menuitem), ui_widgets.recent_files_menu_menubar); /* add recent files to the toolbar Open button */ toolbar_recent_files_menu = gtk_menu_new(); g_object_ref(toolbar_recent_files_menu); geany_menu_button_action_set_menu(GEANY_MENU_BUTTON_ACTION( toolbar_get_action_by_name("Open")), toolbar_recent_files_menu); } static void ui_menu_move(GtkWidget *menu, GtkWidget *old, GtkWidget *new) { g_object_ref(menu); gtk_menu_item_set_submenu(GTK_MENU_ITEM(old), NULL); gtk_menu_item_set_submenu(GTK_MENU_ITEM(new), menu); g_object_unref(menu); } typedef struct GeanySharedMenu { const gchar *menu; const gchar *menubar_item; const gchar *popup_item; } GeanySharedMenu; #define foreach_menu(item, array) \ for (item = array; item->menu; item++) static void on_editor_menu_show(GtkWidget *widget, GeanySharedMenu *items) { GeanySharedMenu *item; foreach_menu(item, items) { GtkWidget *popup = ui_lookup_widget(main_widgets.editor_menu, item->popup_item); GtkWidget *bar = ui_lookup_widget(main_widgets.window, item->menubar_item); GtkWidget *menu = ui_lookup_widget(main_widgets.window, item->menu); ui_menu_move(menu, bar, popup); } } static void on_editor_menu_hide(GtkWidget *widget, GeanySharedMenu *items) { GeanySharedMenu *item; foreach_menu(item, items) { GtkWidget *popup = ui_lookup_widget(main_widgets.editor_menu, item->popup_item); GtkWidget *bar = ui_lookup_widget(main_widgets.window, item->menubar_item); GtkWidget *menu = ui_lookup_widget(main_widgets.window, item->menu); ui_menu_move(menu, popup, bar); } } /* Currently ui_init() is called before keyfile.c stash group code is initialized, * so this is called after that's done. */ void ui_init_prefs(void) { StashGroup *group = stash_group_new(PACKAGE); /* various prefs */ configuration_add_various_pref_group(group, "interface"); stash_group_add_boolean(group, &interface_prefs.show_symbol_list_expanders, "show_symbol_list_expanders", TRUE); stash_group_add_boolean(group, &interface_prefs.compiler_tab_autoscroll, "compiler_tab_autoscroll", TRUE); stash_group_add_string(group, &ui_prefs.statusbar_template, "statusbar_template", _(DEFAULT_STATUSBAR_TEMPLATE)); stash_group_add_boolean(group, &ui_prefs.new_document_after_close, "new_document_after_close", FALSE); stash_group_add_boolean(group, &interface_prefs.msgwin_status_visible, "msgwin_status_visible", TRUE); stash_group_add_boolean(group, &interface_prefs.msgwin_compiler_visible, "msgwin_compiler_visible", TRUE); stash_group_add_boolean(group, &interface_prefs.msgwin_messages_visible, "msgwin_messages_visible", TRUE); stash_group_add_boolean(group, &interface_prefs.msgwin_scribble_visible, "msgwin_scribble_visible", TRUE); stash_group_add_boolean(group, &interface_prefs.warn_on_project_close, "warn_on_project_close", TRUE); stash_group_add_spin_button_integer(group, &interface_prefs.tab_label_len, "tab_label_length", 1000, "spin_tab_label_len"); } /* Used to find out the name of the GtkBuilder retrieved object since * some objects will be GTK_IS_BUILDABLE() and use the GtkBuildable * 'name' property for that and those that don't implement GtkBuildable * will have a "gtk-builder-name" stored in the GObject's data list. */ static const gchar *ui_guess_object_name(GObject *obj) { const gchar *name = NULL; g_return_val_if_fail(G_IS_OBJECT(obj), NULL); if (GTK_IS_BUILDABLE(obj)) name = gtk_buildable_get_name(GTK_BUILDABLE(obj)); if (! name) name = g_object_get_data(obj, "gtk-builder-name"); if (! name) return NULL; return name; } /* Compatibility functions */ GtkWidget *create_edit_menu1(void) { return edit_menu1; } GtkWidget *create_prefs_dialog(void) { return prefs_dialog; } GtkWidget *create_project_dialog(void) { return project_dialog; } GtkWidget *create_toolbar_popup_menu1(void) { return toolbar_popup_menu1; } GtkWidget *create_window1(void) { return window1; } static GtkWidget *ui_get_top_parent(GtkWidget *widget) { GtkWidget *parent; g_return_val_if_fail(GTK_IS_WIDGET(widget), NULL); for (;;) { if (GTK_IS_MENU(widget)) parent = gtk_menu_get_attach_widget(GTK_MENU(widget)); else parent = gtk_widget_get_parent(widget); if (parent == NULL) parent = (GtkWidget*) g_object_get_data(G_OBJECT(widget), "GladeParentKey"); if (parent == NULL) break; widget = parent; } return widget; } void ui_init_builder(void) { gchar *interface_file; const gchar *name; GError *error; GSList *iter, *all_objects; GtkWidget *widget, *toplevel; /* prevent function from being called twice */ if (GTK_IS_BUILDER(builder)) return; builder = gtk_builder_new(); gtk_builder_set_translation_domain(builder, GETTEXT_PACKAGE); error = NULL; interface_file = g_build_filename(app->datadir, "geany.glade", NULL); if (! gtk_builder_add_from_file(builder, interface_file, &error)) { /* Show the user this message so they know WTF happened */ dialogs_show_msgbox_with_secondary(GTK_MESSAGE_ERROR, _("Geany cannot start!"), error->message); /* Aborts */ g_error("Cannot create user-interface: %s", error->message); g_error_free(error); g_free(interface_file); g_object_unref(builder); return; } g_free(interface_file); callbacks_connect(builder); edit_menu1 = GTK_WIDGET(gtk_builder_get_object(builder, "edit_menu1")); prefs_dialog = GTK_WIDGET(gtk_builder_get_object(builder, "prefs_dialog")); project_dialog = GTK_WIDGET(gtk_builder_get_object(builder, "project_dialog")); toolbar_popup_menu1 = GTK_WIDGET(gtk_builder_get_object(builder, "toolbar_popup_menu1")); window1 = GTK_WIDGET(gtk_builder_get_object(builder, "window1")); g_object_set_data(G_OBJECT(edit_menu1), "edit_menu1", edit_menu1); g_object_set_data(G_OBJECT(prefs_dialog), "prefs_dialog", prefs_dialog); g_object_set_data(G_OBJECT(project_dialog), "project_dialog", project_dialog); g_object_set_data(G_OBJECT(toolbar_popup_menu1), "toolbar_popup_menu1", toolbar_popup_menu1); g_object_set_data(G_OBJECT(window1), "window1", window1); all_objects = gtk_builder_get_objects(builder); for (iter = all_objects; iter != NULL; iter = g_slist_next(iter)) { if (! GTK_IS_WIDGET(iter->data)) continue; widget = GTK_WIDGET(iter->data); name = ui_guess_object_name(G_OBJECT(widget)); if (! name) { g_warning("Unable to get name from GtkBuilder object"); continue; } else { /* Set a default name for use from CSS by name */ gtk_widget_set_name(widget, name); } toplevel = ui_get_top_parent(widget); if (toplevel) ui_hookup_widget(toplevel, widget, name); } g_slist_free(all_objects); } static void load_css_theme(const gchar *fn, guint priority) { GtkCssProvider *provider = gtk_css_provider_new(); GError *error = NULL; if (! gtk_css_provider_load_from_path(provider, fn, &error)) { g_warning("Failed to load custom CSS: %s", error->message); g_error_free(error); return; } gtk_style_context_add_provider_for_screen(gdk_screen_get_default(), GTK_STYLE_PROVIDER(provider), priority); geany_debug("Loaded GTK+ CSS theme '%s'", fn); g_object_unref(provider); } static void init_css_styles(void) { gchar *theme_fn; // load the main geany.css file from system data dir theme_fn = g_build_filename(app->datadir, "geany.css", NULL); load_css_theme(theme_fn, GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); g_free(theme_fn); // load themes to handle breakage between various GTK+ versions const struct { guint min_version; guint max_version; const gchar *file; } css_files[] = { /* Unused now but can be used to load css for different GTK versions, such as * { 20, G_MAXUINT, "geany-3.20.css" }, * { 0, 19, "geany-3.0.css" }, */ }; guint gtk_version = gtk_get_minor_version(); for (guint i = 0; i < G_N_ELEMENTS(css_files); i++) { if (gtk_version >= css_files[i].min_version && gtk_version <= css_files[i].max_version) { theme_fn = g_build_filename(app->datadir, css_files[i].file, NULL); load_css_theme(theme_fn, GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); g_free(theme_fn); } } // if the user provided a geany.css file in their config dir, try and load that theme_fn = g_build_filename(app->configdir, "geany.css", NULL); if (g_file_test(theme_fn, G_FILE_TEST_EXISTS)) load_css_theme(theme_fn, GTK_STYLE_PROVIDER_PRIORITY_USER); g_free(theme_fn); } static void add_css_config_file_item(void) { gchar *theme_fn; theme_fn = g_build_filename(app->configdir, "geany.css", NULL); ui_add_config_file_menu_item(theme_fn, NULL, NULL); g_free(theme_fn); } void ui_init(void) { init_css_styles(); init_recent_files(); ui_widgets.statusbar = ui_lookup_widget(main_widgets.window, "statusbar"); ui_widgets.print_page_setup = ui_lookup_widget(main_widgets.window, "page_setup1"); main_widgets.progressbar = progress_bar_create(); /* current word sensitive items */ widgets.popup_goto_items[0] = ui_lookup_widget(main_widgets.editor_menu, "goto_tag_definition2"); widgets.popup_goto_items[1] = ui_lookup_widget(main_widgets.editor_menu, "context_action1"); widgets.popup_goto_items[2] = ui_lookup_widget(main_widgets.editor_menu, "find_usage2"); widgets.popup_goto_items[3] = ui_lookup_widget(main_widgets.editor_menu, "find_document_usage2"); widgets.popup_copy_items[0] = ui_lookup_widget(main_widgets.editor_menu, "cut1"); widgets.popup_copy_items[1] = ui_lookup_widget(main_widgets.editor_menu, "copy1"); widgets.popup_copy_items[2] = ui_lookup_widget(main_widgets.editor_menu, "delete1"); widgets.menu_copy_items[0] = ui_lookup_widget(main_widgets.window, "menu_cut1"); widgets.menu_copy_items[1] = ui_lookup_widget(main_widgets.window, "menu_copy1"); widgets.menu_copy_items[2] = ui_lookup_widget(main_widgets.window, "menu_delete1"); widgets.menu_insert_include_items[0] = ui_lookup_widget(main_widgets.editor_menu, "insert_include1"); widgets.menu_insert_include_items[1] = ui_lookup_widget(main_widgets.window, "insert_include2"); widgets.save_buttons[0] = ui_lookup_widget(main_widgets.window, "menu_save1"); widgets.save_buttons[2] = ui_lookup_widget(main_widgets.window, "menu_save_all1"); widgets.redo_items[0] = ui_lookup_widget(main_widgets.editor_menu, "redo1"); widgets.redo_items[1] = ui_lookup_widget(main_widgets.window, "menu_redo2"); widgets.undo_items[0] = ui_lookup_widget(main_widgets.editor_menu, "undo1"); widgets.undo_items[1] = ui_lookup_widget(main_widgets.window, "menu_undo2"); /* reparent context submenus as needed */ { GeanySharedMenu arr[] = { {"commands2_menu", "commands2", "commands1"}, {"menu_format1_menu", "menu_format1", "menu_format2"}, {"more1_menu", "more1", "search2"}, {NULL, NULL, NULL} }; static GeanySharedMenu items[G_N_ELEMENTS(arr)]; memcpy(items, arr, sizeof(arr)); g_signal_connect(main_widgets.editor_menu, "show", G_CALLBACK(on_editor_menu_show), items); g_signal_connect(main_widgets.editor_menu, "hide", G_CALLBACK(on_editor_menu_hide), items); } ui_init_toolbar_widgets(); init_document_widgets(); create_config_files_menu(); add_css_config_file_item(); } void ui_finalize_builder(void) { if (GTK_IS_BUILDER(builder)) g_object_unref(builder); /* cleanup refs lingering even after GtkBuilder is destroyed */ if (GTK_IS_WIDGET(edit_menu1)) gtk_widget_destroy(edit_menu1); if (GTK_IS_WIDGET(prefs_dialog)) gtk_widget_destroy(prefs_dialog); if (GTK_IS_WIDGET(project_dialog)) gtk_widget_destroy(project_dialog); if (GTK_IS_WIDGET(toolbar_popup_menu1)) gtk_widget_destroy(toolbar_popup_menu1); if (GTK_IS_WIDGET(window1)) gtk_widget_destroy(window1); } static void auto_separator_update(GeanyAutoSeparator *autosep) { g_return_if_fail(autosep->item_count >= 0); if (autosep->widget) { if (autosep->item_count > 0) ui_widget_show_hide(autosep->widget, autosep->show_count > 0); else gtk_widget_destroy(autosep->widget); } } static void on_auto_separator_item_show_hide(GtkWidget *widget, gpointer user_data) { GeanyAutoSeparator *autosep = user_data; if (gtk_widget_get_visible(widget)) autosep->show_count++; else autosep->show_count--; auto_separator_update(autosep); } static void on_auto_separator_item_destroy(GtkWidget *widget, gpointer user_data) { GeanyAutoSeparator *autosep = user_data; autosep->item_count--; autosep->item_count = MAX(autosep->item_count, 0); /* gtk_widget_get_visible() won't work now the widget is being destroyed, * so assume widget was visible */ autosep->show_count--; autosep->show_count = MAX(autosep->item_count, 0); auto_separator_update(autosep); } /* Show the separator widget if @a item or another is visible. */ /* Note: This would be neater taking a widget argument, setting a "visible-count" * property, and using reference counting to keep the widget alive whilst its visible group * is alive. */ void ui_auto_separator_add_ref(GeanyAutoSeparator *autosep, GtkWidget *item) { /* set widget ptr NULL when widget destroyed */ if (autosep->item_count == 0) g_signal_connect(autosep->widget, "destroy", G_CALLBACK(gtk_widget_destroyed), &autosep->widget); if (gtk_widget_get_visible(item)) autosep->show_count++; autosep->item_count++; auto_separator_update(autosep); g_signal_connect(item, "show", G_CALLBACK(on_auto_separator_item_show_hide), autosep); g_signal_connect(item, "hide", G_CALLBACK(on_auto_separator_item_show_hide), autosep); g_signal_connect(item, "destroy", G_CALLBACK(on_auto_separator_item_destroy), autosep); } /** * Sets @a text as the contents of the tooltip for @a widget. * * @param widget The widget the tooltip should be set for. * @param text The text for the tooltip. * * @since 0.16 * @deprecated 0.21 use gtk_widget_set_tooltip_text() instead */ GEANY_API_SYMBOL void ui_widget_set_tooltip_text(GtkWidget *widget, const gchar *text) { gtk_widget_set_tooltip_text(widget, text); } /** Returns a widget from a name in a component, usually created by Glade. * Call it with the toplevel widget in the component (i.e. a window/dialog), * or alternatively any widget in the component, and the name of the widget * you want returned. * @param widget Widget with the @a widget_name property set. * @param widget_name Name to lookup. * * @return @transfer{none} The widget found. * @see ui_hookup_widget(). * * @since 0.16 */ GEANY_API_SYMBOL GtkWidget *ui_lookup_widget(GtkWidget *widget, const gchar *widget_name) { GtkWidget *parent, *found_widget; g_return_val_if_fail(widget != NULL, NULL); g_return_val_if_fail(widget_name != NULL, NULL); for (;;) { if (GTK_IS_MENU(widget)) parent = gtk_menu_get_attach_widget(GTK_MENU(widget)); else parent = gtk_widget_get_parent(widget); if (parent == NULL) parent = (GtkWidget*) g_object_get_data(G_OBJECT(widget), "GladeParentKey"); if (parent == NULL) break; widget = parent; } found_widget = (GtkWidget*) g_object_get_data(G_OBJECT(widget), widget_name); if (G_UNLIKELY(found_widget == NULL)) g_warning("Widget not found: %s", widget_name); return found_widget; } /* wraps gtk_builder_get_object() * unlike ui_lookup_widget(), it does only support getting object created from the main * UI file, but it can fetch any object, not only widgets */ gpointer ui_builder_get_object (const gchar *name) { return gtk_builder_get_object (builder, name); } /* Progress Bar */ static guint progress_bar_timer_id = 0; static GtkWidget *progress_bar_create(void) { GtkWidget *bar = gtk_progress_bar_new(); /* Set the progressbar's height to 1 to fit it in the statusbar */ gtk_widget_set_size_request(bar, -1, 1); gtk_box_pack_start (GTK_BOX(ui_widgets.statusbar), bar, FALSE, FALSE, 3); return bar; } static gboolean progress_bar_pulse(gpointer data) { gtk_progress_bar_pulse(GTK_PROGRESS_BAR(main_widgets.progressbar)); return TRUE; } /** * Starts a constantly pulsing progressbar in the right corner of the statusbar * (if the statusbar is visible). This is a convenience function which adds a timer to * pulse the progressbar constantly until ui_progress_bar_stop() is called. * You can use this function when you have time consuming asynchronous operation and want to * display some activity in the GUI and when you don't know about detailed progress steps. * The progressbar widget is hidden by default when it is not active. This function and * ui_progress_bar_stop() will show and hide it automatically for you. * * You can also access the progressbar widget directly using @c geany->main_widgets->progressbar * and use the GtkProgressBar API to set discrete fractions to display better progress information. * In this case, you need to show and hide the widget yourself. You can find some example code * in @c src/printing.c. * * @param text @nullable The text to be shown as the progress bar label or @c NULL to leave it empty. * * @since 0.16 **/ GEANY_API_SYMBOL void ui_progress_bar_start(const gchar *text) { g_return_if_fail(progress_bar_timer_id == 0); if (! interface_prefs.statusbar_visible) return; gtk_progress_bar_set_text(GTK_PROGRESS_BAR(main_widgets.progressbar), text); progress_bar_timer_id = g_timeout_add(200, progress_bar_pulse, NULL); gtk_widget_show(GTK_WIDGET(main_widgets.progressbar)); } /** Stops a running progress bar and hides the widget again. * * @since 0.16 **/ GEANY_API_SYMBOL void ui_progress_bar_stop(void) { gtk_widget_hide(GTK_WIDGET(main_widgets.progressbar)); if (progress_bar_timer_id != 0) { g_source_remove(progress_bar_timer_id); progress_bar_timer_id = 0; } } static gint compare_menu_item_labels(gconstpointer a, gconstpointer b) { GtkMenuItem *item_a = GTK_MENU_ITEM(a); GtkMenuItem *item_b = GTK_MENU_ITEM(b); gchar *sa, *sb; gint result; /* put entries with submenus at the start of the menu */ if (gtk_menu_item_get_submenu(item_a) && !gtk_menu_item_get_submenu(item_b)) return -1; else if (!gtk_menu_item_get_submenu(item_a) && gtk_menu_item_get_submenu(item_b)) return 1; sa = ui_menu_item_get_text(item_a); sb = ui_menu_item_get_text(item_b); result = utils_str_casecmp(sa, sb); g_free(sa); g_free(sb); return result; } /* Currently @a menu should contain only GtkMenuItems with labels. */ void ui_menu_sort_by_label(GtkMenu *menu) { GList *list = gtk_container_get_children(GTK_CONTAINER(menu)); GList *node; gint pos; list = g_list_sort(list, compare_menu_item_labels); pos = 0; foreach_list(node, list) { menu_reorder_child(menu, node->data, pos); pos++; } g_list_free(list); } void ui_label_set_markup(GtkLabel *label, const gchar *format, ...) { va_list a; gchar *text; va_start(a, format); text = g_markup_vprintf_escaped(format, a); va_end(a); gtk_label_set_text(label, text); gtk_label_set_use_markup(label, TRUE); g_free(text); } GtkWidget *ui_label_new_bold(const gchar *text) { GtkWidget *label; label = gtk_label_new(NULL); ui_label_set_markup(GTK_LABEL(label), "%s", text); return label; } /** @girskip * Adds a list of document items to @a menu. * @param menu Menu. * @param active @nullable Which document to highlight, or @c NULL. * @param callback is used for each menu item's @c "activate" signal and will be * passed the corresponding document pointer as @c user_data. * @warning You should check @c doc->is_valid in the callback. * @since 0.19 **/ GEANY_API_SYMBOL void ui_menu_add_document_items(GtkMenu *menu, GeanyDocument *active, GCallback callback) { ui_menu_add_document_items_sorted(menu, active, callback, NULL); } /** @girskip * Adds a list of document items to @a menu. * * @a compare_func might be NULL to not sort the documents in the menu. In this case, * the order of the document tabs is used. * * See document_compare_by_display_name() for an example sort function. * * @param menu Menu. * @param active @nullable Which document to highlight, or @c NULL. * @param callback is used for each menu item's @c "activate" signal and will be passed * the corresponding document pointer as @c user_data. * @param compare_func is used to sort the list. Might be @c NULL to not sort the list. * @warning You should check @c doc->is_valid in the callback. * @since 0.21 **/ GEANY_API_SYMBOL void ui_menu_add_document_items_sorted(GtkMenu *menu, GeanyDocument *active, GCallback callback, GCompareFunc compare_func) { GtkWidget *menu_item, *menu_item_label, *image; GeanyDocument *doc; guint i, len; gchar *base_name; GPtrArray *sorted_documents; len = (guint) gtk_notebook_get_n_pages(GTK_NOTEBOOK(main_widgets.notebook)); sorted_documents = g_ptr_array_sized_new(len); /* copy the documents_array into the new one */ foreach_document(i) { g_ptr_array_add(sorted_documents, documents[i]); } if (compare_func == NULL) compare_func = document_compare_by_tab_order; /* and now sort it */ g_ptr_array_sort(sorted_documents, compare_func); for (i = 0; i < sorted_documents->len; i++) { doc = g_ptr_array_index(sorted_documents, i); base_name = g_path_get_basename(DOC_FILENAME(doc)); menu_item = gtk_image_menu_item_new_with_label(base_name); image = gtk_image_new_from_gicon(doc->file_type->icon, GTK_ICON_SIZE_MENU); gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menu_item), image); gtk_widget_set_tooltip_text(menu_item, DOC_FILENAME(doc)); gtk_widget_show(menu_item); gtk_container_add(GTK_CONTAINER(menu), menu_item); g_signal_connect(menu_item, "activate", callback, doc); menu_item_label = gtk_bin_get_child(GTK_BIN(menu_item)); gtk_widget_set_name(menu_item_label, document_get_status_widget_class(doc)); if (doc == active) ui_label_set_markup(GTK_LABEL(menu_item_label), "%s", base_name); g_free(base_name); } g_ptr_array_free(sorted_documents, TRUE); } /** Checks whether the passed @a keyval is the Enter or Return key. * There are three different Enter/Return key values * (@c GDK_KEY_Return, @c GDK_KEY_ISO_Enter, @c GDK_KEY_KP_Enter). * This is just a convenience function. * @param keyval A keyval. * @return @c TRUE if @a keyval is the one of the Enter/Return key values, otherwise @c FALSE. * @since 0.19 */ GEANY_API_SYMBOL gboolean ui_is_keyval_enter_or_return(guint keyval) { return (keyval == GDK_KEY_Return || keyval == GDK_KEY_ISO_Enter|| keyval == GDK_KEY_KP_Enter); } /** Reads an integer from the GTK default settings registry * (see https://docs.gtk.org/gtk3/class.Settings.html). * @param property_name The property to read. * @param default_value The default value in case the value could not be read. * @return The value for the property if it exists, otherwise the @a default_value. * @since 0.19 */ GEANY_API_SYMBOL gint ui_get_gtk_settings_integer(const gchar *property_name, gint default_value) { if (g_object_class_find_property(G_OBJECT_GET_CLASS(G_OBJECT( gtk_settings_get_default())), property_name)) { gint value; g_object_get(G_OBJECT(gtk_settings_get_default()), property_name, &value, NULL); return value; } else return default_value; } void ui_editable_insert_text_callback(GtkEditable *editable, gchar *new_text, gint new_text_len, gint *position, gpointer data) { gboolean first = position != NULL && *position == 0; gint i; if (new_text_len == -1) new_text_len = (gint) strlen(new_text); for (i = 0; i < new_text_len; i++, new_text++) { if ((!first || !strchr("+-", *new_text)) && !isdigit(*new_text)) { g_signal_stop_emission_by_name(editable, "insert-text"); break; } first = FALSE; } } /* gets the icon that applies to a particular MIME type */ GIcon *ui_get_mime_icon(const gchar *mime_type) { GIcon *icon = NULL; gchar *ctype; ctype = g_content_type_from_mime_type(mime_type); if (ctype) { GdkScreen *screen = gdk_screen_get_default(); icon = g_content_type_get_icon(ctype); if (screen && icon) { GtkIconInfo *icon_info; icon_info = gtk_icon_theme_lookup_by_gicon(gtk_icon_theme_get_for_screen(screen), icon, 16, 0); if (!icon_info) { g_object_unref(icon); icon = NULL; } else gtk_icon_info_free(icon_info); } g_free(ctype); } /* fallback if icon lookup failed, like it might happen on Windows (?) */ if (! icon) { const gchar *icon_name = "text-x-generic"; if (strstr(mime_type, "directory")) icon_name = "folder"; icon = g_themed_icon_new(icon_name); } return icon; } void ui_focus_current_document(void) { GeanyDocument *doc = document_get_current(); if (doc != NULL) document_grab_focus(doc); } /** Finds the label text associated with stock_id * @param stock_id stock_id to lookup e.g. @c GTK_STOCK_OPEN. * @return The label text for stock * @since Geany 1.22 */ GEANY_API_SYMBOL const gchar *ui_lookup_stock_label(const gchar *stock_id) { GtkStockItem item; if (gtk_stock_lookup(stock_id, &item)) return item.label; g_warning("No stock id '%s'!", stock_id); return NULL; } /* finds the next iter at any level * @param iter in/out, the current iter, will be changed to the next one * @param down whether to try the child iter * @return TRUE if there @p iter was set, or FALSE if there is no next iter */ gboolean ui_tree_model_iter_any_next(GtkTreeModel *model, GtkTreeIter *iter, gboolean down) { GtkTreeIter guess; GtkTreeIter copy = *iter; /* go down if the item has children */ if (down && gtk_tree_model_iter_children(model, &guess, iter)) *iter = guess; /* or to the next item at the same level */ else if (gtk_tree_model_iter_next(model, ©)) *iter = copy; /* or to the next item at a parent level */ else if (gtk_tree_model_iter_parent(model, &guess, iter)) { copy = guess; while (TRUE) { if (gtk_tree_model_iter_next(model, ©)) { *iter = copy; return TRUE; } else if (gtk_tree_model_iter_parent(model, ©, &guess)) guess = copy; else return FALSE; } } else return FALSE; return TRUE; } GtkWidget *ui_create_encodings_combo_box(gboolean has_detect, gint default_enc) { GtkCellRenderer *renderer; GtkTreeIter iter; GtkWidget *combo = gtk_combo_box_new(); GtkTreeStore *store = encodings_encoding_store_new(has_detect); if (default_enc < 0 || default_enc >= GEANY_ENCODINGS_MAX) default_enc = has_detect ? GEANY_ENCODINGS_MAX : GEANY_ENCODING_NONE; gtk_combo_box_set_model(GTK_COMBO_BOX(combo), GTK_TREE_MODEL(store)); if (encodings_encoding_store_get_iter(store, &iter, default_enc)) gtk_combo_box_set_active_iter(GTK_COMBO_BOX(combo), &iter); renderer = gtk_cell_renderer_text_new(); gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combo), renderer, TRUE); gtk_cell_layout_set_cell_data_func(GTK_CELL_LAYOUT(combo), renderer, encodings_encoding_store_cell_data_func, NULL, NULL); return combo; } gint ui_encodings_combo_box_get_active_encoding(GtkComboBox *combo) { GtkTreeIter iter; gint enc = GEANY_ENCODING_NONE; /* there should always be an active iter anyway, but we check just in case */ if (gtk_combo_box_get_active_iter(combo, &iter)) { GtkTreeModel *model = gtk_combo_box_get_model(combo); enc = encodings_encoding_store_get_encoding(GTK_TREE_STORE(model), &iter); } return enc; } gboolean ui_encodings_combo_box_set_active_encoding(GtkComboBox *combo, gint enc) { GtkTreeIter iter; GtkTreeModel *model = gtk_combo_box_get_model(combo); if (encodings_encoding_store_get_iter(GTK_TREE_STORE(model), &iter, enc)) { gtk_combo_box_set_active_iter(combo, &iter); return TRUE; } return FALSE; } geany-2.0/src/geanymenubuttonaction.c0000644000175000017500000001472214514252267014772 00000000000000/* * geanymenubuttonaction.c - this file is part of Geany, a fast and lightweight IDE * * Copyright 2009 The Geany contributors * * This program 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; either version 2 of the License, or * (at your option) any later version. * * This program 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /* GtkAction subclass to provide a GtkMenuToolButton in a toolbar. * This class is missing the action_create_menu_item() function and so can't be * used for creating menu items. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include "geanymenubuttonaction.h" #include "utils.h" typedef struct _GeanyMenubuttonActionPrivate GeanyMenubuttonActionPrivate; #define GEANY_MENU_BUTTON_ACTION_GET_PRIVATE(obj) (GEANY_MENU_BUTTON_ACTION(obj)->priv) struct _GeanyMenubuttonActionPrivate { GtkWidget *menu; gchar *tooltip_arrow; }; enum { PROP_0, PROP_TOOLTIP_ARROW }; enum { BUTTON_CLICKED, LAST_SIGNAL }; static guint signals[LAST_SIGNAL]; G_DEFINE_TYPE(GeanyMenubuttonAction, geany_menu_button_action, GTK_TYPE_ACTION) static void geany_menu_button_action_finalize(GObject *object) { GeanyMenubuttonActionPrivate *priv = GEANY_MENU_BUTTON_ACTION_GET_PRIVATE(object); g_object_unref(priv->menu); g_free(priv->tooltip_arrow); (* G_OBJECT_CLASS(geany_menu_button_action_parent_class)->finalize)(object); } static void delegate_button_activated(GtkAction *action) { g_signal_emit(action, signals[BUTTON_CLICKED], 0); } static void geany_menu_button_action_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { switch (prop_id) { case PROP_TOOLTIP_ARROW: { GeanyMenubuttonActionPrivate *priv = GEANY_MENU_BUTTON_ACTION_GET_PRIVATE(object); g_free(priv->tooltip_arrow); priv->tooltip_arrow = g_value_dup_string(value); break; } default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; } } static GtkWidget *geany_menu_button_action_create_tool_item(GtkAction *action) { GtkWidget *toolitem; GeanyMenubuttonActionPrivate *priv = GEANY_MENU_BUTTON_ACTION_GET_PRIVATE(action); toolitem = g_object_new(GTK_TYPE_MENU_TOOL_BUTTON, NULL); gtk_menu_tool_button_set_arrow_tooltip_text(GTK_MENU_TOOL_BUTTON(toolitem), priv->tooltip_arrow); return toolitem; } static void geany_menu_button_action_class_init(GeanyMenubuttonActionClass *klass) { GtkActionClass *action_class = GTK_ACTION_CLASS(klass); GObjectClass *g_object_class = G_OBJECT_CLASS(klass); g_object_class->finalize = geany_menu_button_action_finalize; g_object_class->set_property = geany_menu_button_action_set_property; action_class->activate = delegate_button_activated; action_class->create_tool_item = geany_menu_button_action_create_tool_item; action_class->toolbar_item_type = GTK_TYPE_MENU_TOOL_BUTTON; g_type_class_add_private(klass, sizeof(GeanyMenubuttonActionPrivate)); g_object_class_install_property(g_object_class, PROP_TOOLTIP_ARROW, g_param_spec_string( "tooltip-arrow", "Arrow tooltip", "A special tooltip for the arrow button", "", G_PARAM_WRITABLE)); signals[BUTTON_CLICKED] = g_signal_new("button-clicked", G_TYPE_FROM_CLASS(klass), (GSignalFlags) 0, 0, 0, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); } static void geany_menu_button_action_init(GeanyMenubuttonAction *action) { GeanyMenubuttonActionPrivate *priv; action->priv = G_TYPE_INSTANCE_GET_PRIVATE(action, GEANY_MENU_BUTTON_ACTION_TYPE, GeanyMenubuttonActionPrivate); priv = action->priv; priv->tooltip_arrow = NULL; priv->menu = NULL; } GtkAction *geany_menu_button_action_new(const gchar *name, const gchar *label, const gchar *tooltip, const gchar *tooltip_arrow, const gchar *stock_id) { GtkAction *action = g_object_new(GEANY_MENU_BUTTON_ACTION_TYPE, "name", name, "label", label, "tooltip", tooltip, "tooltip-arrow", tooltip_arrow, "stock-id", stock_id, NULL); return action; } GtkWidget *geany_menu_button_action_get_menu(GeanyMenubuttonAction *action) { GeanyMenubuttonActionPrivate *priv; g_return_val_if_fail(action != NULL, NULL); priv = GEANY_MENU_BUTTON_ACTION_GET_PRIVATE(action); return priv->menu; } static void menu_items_changed_cb(GtkContainer *container, GtkWidget *widget, GeanyMenubuttonAction *action) { GeanyMenubuttonActionPrivate *priv; gboolean enable; GSList *l; g_return_if_fail(action != NULL); priv = GEANY_MENU_BUTTON_ACTION_GET_PRIVATE(action); if (priv->menu != NULL) { GList *children = gtk_container_get_children(GTK_CONTAINER(priv->menu)); enable = (g_list_length(children) > 0); g_list_free(children); } else enable = FALSE; foreach_slist(l, gtk_action_get_proxies(GTK_ACTION(action))) { /* On Windows a GtkImageMenuItem proxy is created for whatever reason. So we filter * by type and act only on GtkMenuToolButton proxies. */ /* TODO find why the GtkImageMenuItem proxy is created */ if (! GTK_IS_MENU_TOOL_BUTTON(l->data)) continue; if (enable) { if (gtk_menu_tool_button_get_menu(GTK_MENU_TOOL_BUTTON(l->data)) == NULL) gtk_menu_tool_button_set_menu(GTK_MENU_TOOL_BUTTON(l->data), priv->menu); } else gtk_menu_tool_button_set_menu(GTK_MENU_TOOL_BUTTON(l->data), NULL); } } void geany_menu_button_action_set_menu(GeanyMenubuttonAction *action, GtkWidget *menu) { GeanyMenubuttonActionPrivate *priv; g_return_if_fail(action != NULL); priv = GEANY_MENU_BUTTON_ACTION_GET_PRIVATE(action); if (priv->menu != NULL && GTK_IS_WIDGET(priv->menu)) g_signal_handlers_disconnect_by_func(priv->menu, menu_items_changed_cb, action); if (menu != NULL) { g_signal_connect(menu, "add", G_CALLBACK(menu_items_changed_cb), action); g_signal_connect(menu, "remove", G_CALLBACK(menu_items_changed_cb), action); } priv->menu = menu; menu_items_changed_cb(GTK_CONTAINER(menu), NULL, action); } geany-2.0/src/geany.h0000644000175000017500000000524414514252267011457 00000000000000/* * geany.h - this file is part of Geany, a fast and lightweight IDE * * Copyright 2005 The Geany contributors * * This program 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; either version 2 of the License, or * (at your option) any later version. * * This program 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /* Main header - should be included first in all source files. * externs and function prototypes are implemented in main.c. */ #ifndef GEANY_H #define GEANY_H 1 /* This is included here for compatibility with when GeanyApp used to be * defined in this header. Some plugins (ex. GeanyLua) include individual * headers instead of geanyplugin.h for some reason so they wouldn't * get the GeanyApp definition if this isn't here. */ #include "app.h" #include G_BEGIN_DECLS /* for detailed description look in the documentation, things are not * listed in the documentation should not be changed */ #define GEANY_FILEDEFS_SUBDIR "filedefs" #define GEANY_TEMPLATES_SUBDIR "templates" #define GEANY_TAGS_SUBDIR "tags" #define GEANY_CODENAME "Pryce" #define GEANY_HOMEPAGE "https://www.geany.org/" #define GEANY_WIKI "https://wiki.geany.org/" #define GEANY_BUG_REPORT "https://www.geany.org/Support/Bugs" #define GEANY_DONATE "https://www.geany.org/service/donate/" #define GEANY_STRING_UNTITLED _("untitled") #define GEANY_DEFAULT_DIALOG_HEIGHT 350 #define GEANY_WINDOW_DEFAULT_WIDTH 900 #define GEANY_WINDOW_DEFAULT_HEIGHT 600 #ifndef G_GNUC_WARN_UNUSED_RESULT #define G_GNUC_WARN_UNUSED_RESULT #endif #if defined(GEANY_PRIVATE) || defined(GEANY_DISABLE_DEPRECATION_WARNINGS) # define GEANY_DEPRECATED # define GEANY_DEPRECATED_FOR(x) #else # define GEANY_DEPRECATED G_GNUC_DEPRECATED # define GEANY_DEPRECATED_FOR(x) G_GNUC_DEPRECATED_FOR(x) #endif /* Re-defined by plugindata.h as something else */ #ifndef GEANY # define GEANY(symbol_name) symbol_name #endif #ifdef GEANY_PRIVATE /* prototype is here so that all files can use it. */ void geany_debug(gchar const *format, ...) G_GNUC_PRINTF (1, 2); #endif /* GEANY_PRIVATE */ G_END_DECLS #endif /* GEANY_H */ geany-2.0/src/geanywraplabel.c0000644000175000017500000001532714514252267013347 00000000000000/* * geanywraplabel.c - this file is part of Geany, a fast and lightweight IDE * * Copyright 2009 The Geany contributors * * This program 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; either version 2 of the License, or * (at your option) any later version. * * This program 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /* * A GtkLabel subclass that can wrap to any width, unlike GtkLabel which has a fixed wrap point. * (inspired by libview's WrapLabel, https://view.sourceforge.net/) */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include "geanywraplabel.h" struct _GeanyWrapLabelClass { GtkLabelClass parent_class; }; typedef struct { gint wrap_width; gint wrap_height; } GeanyWrapLabelPrivate; struct _GeanyWrapLabel { GtkLabel parent; GeanyWrapLabelPrivate *priv; }; static gboolean geany_wrap_label_draw(GtkWidget *widget, cairo_t *cr); static void geany_wrap_label_get_preferred_width (GtkWidget *widget, gint *minimal_width, gint *natural_width); static void geany_wrap_label_get_preferred_height (GtkWidget *widget, gint *minimal_height, gint *natural_height); static void geany_wrap_label_get_preferred_width_for_height (GtkWidget *widget, gint height, gint *minimal_width, gint *natural_width); static void geany_wrap_label_get_preferred_height_for_width (GtkWidget *widget, gint width, gint *minimal_height, gint *natural_height); static GtkSizeRequestMode geany_wrap_label_get_request_mode(GtkWidget *widget); static void geany_wrap_label_size_allocate (GtkWidget *widget, GtkAllocation *alloc); static void geany_wrap_label_set_wrap_width (GtkWidget *widget, gint width); static void geany_wrap_label_label_notify (GObject *object, GParamSpec *pspec, gpointer data); G_DEFINE_TYPE(GeanyWrapLabel, geany_wrap_label, GTK_TYPE_LABEL) static void geany_wrap_label_class_init(GeanyWrapLabelClass *klass) { GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass); widget_class->size_allocate = geany_wrap_label_size_allocate; widget_class->draw = geany_wrap_label_draw; widget_class->get_preferred_width = geany_wrap_label_get_preferred_width; widget_class->get_preferred_width_for_height = geany_wrap_label_get_preferred_width_for_height; widget_class->get_preferred_height = geany_wrap_label_get_preferred_height; widget_class->get_preferred_height_for_width = geany_wrap_label_get_preferred_height_for_width; widget_class->get_request_mode = geany_wrap_label_get_request_mode; g_type_class_add_private(klass, sizeof (GeanyWrapLabelPrivate)); } static void geany_wrap_label_init(GeanyWrapLabel *self) { self->priv = G_TYPE_INSTANCE_GET_PRIVATE(self, GEANY_WRAP_LABEL_TYPE, GeanyWrapLabelPrivate); self->priv->wrap_width = 0; self->priv->wrap_height = 0; g_signal_connect(self, "notify::label", G_CALLBACK(geany_wrap_label_label_notify), NULL); gtk_misc_set_alignment(GTK_MISC(self), 0.0, 0.0); } /* Sets the point at which the text should wrap. */ static void geany_wrap_label_set_wrap_width(GtkWidget *widget, gint width) { GeanyWrapLabel *self = GEANY_WRAP_LABEL(widget); PangoLayout *layout; if (width <= 0) return; layout = gtk_label_get_layout(GTK_LABEL(widget)); /* * We may need to reset the wrap width, so do this regardless of whether * or not we've changed the width. */ pango_layout_set_width(layout, width * PANGO_SCALE); pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR); pango_layout_get_pixel_size(layout, NULL, &self->priv->wrap_height); if (self->priv->wrap_width != width) { self->priv->wrap_width = width; gtk_widget_queue_resize(widget); } } /* updates the wrap width when the label text changes */ static void geany_wrap_label_label_notify(GObject *object, GParamSpec *pspec, gpointer data) { GeanyWrapLabel *self = GEANY_WRAP_LABEL(object); geany_wrap_label_set_wrap_width(GTK_WIDGET(object), self->priv->wrap_width); } /* makes sure the layout is setup for rendering and chains to parent renderer */ static gboolean geany_wrap_label_draw(GtkWidget *widget, cairo_t *cr) { GeanyWrapLabel *self = GEANY_WRAP_LABEL(widget); PangoLayout *layout = gtk_label_get_layout(GTK_LABEL(widget)); pango_layout_set_width(layout, self->priv->wrap_width * PANGO_SCALE); pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR); return (* GTK_WIDGET_CLASS(geany_wrap_label_parent_class)->draw)(widget, cr); } static void geany_wrap_label_get_preferred_width (GtkWidget *widget, gint *minimal_width, gint *natural_width) { *minimal_width = *natural_width = 0; } static void geany_wrap_label_get_preferred_width_for_height (GtkWidget *widget, gint height, gint *minimal_width, gint *natural_width) { PangoLayout *layout = gtk_label_get_layout(GTK_LABEL(widget));; pango_layout_set_height(layout, height * PANGO_SCALE); pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR); pango_layout_get_pixel_size(layout, natural_width, NULL); *minimal_width = 0; } static void geany_wrap_label_get_preferred_height (GtkWidget *widget, gint *minimal_height, gint *natural_height) { *minimal_height = *natural_height = GEANY_WRAP_LABEL(widget)->priv->wrap_height; } static void geany_wrap_label_get_preferred_height_for_width (GtkWidget *widget, gint width, gint *minimal_height, gint *natural_height) { PangoLayout *layout = gtk_label_get_layout(GTK_LABEL(widget)); pango_layout_set_width(layout, width * PANGO_SCALE); pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR); pango_layout_get_pixel_size(layout, NULL, natural_height); *minimal_height = *natural_height; } static GtkSizeRequestMode geany_wrap_label_get_request_mode(GtkWidget *widget) { return GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT; } /* Sets the wrap width to the width allocated to us. */ static void geany_wrap_label_size_allocate(GtkWidget *widget, GtkAllocation *alloc) { GtkWidget *parent; (* GTK_WIDGET_CLASS(geany_wrap_label_parent_class)->size_allocate)(widget, alloc); geany_wrap_label_set_wrap_width(widget, alloc->width); /* ask the parent to recompute our size, because it seems GTK size * caching is too aggressive */ parent = gtk_widget_get_parent(widget); if (GTK_IS_CONTAINER(parent)) gtk_container_check_resize(GTK_CONTAINER(parent)); } GtkWidget *geany_wrap_label_new(const gchar *text) { return g_object_new(GEANY_WRAP_LABEL_TYPE, "label", text, NULL); } geany-2.0/src/pluginutils.c0000644000175000017500000006113114514252267012723 00000000000000/* * pluginutils.c - this file is part of Geany, a fast and lightweight IDE * * Copyright 2005 The Geany contributors * * This program 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; either version 2 of the License, or * (at your option) any later version. * * This program 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /** @file pluginutils.h * Plugin utility functions. * These functions all take the @ref geany_plugin symbol as their first argument. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #ifdef HAVE_PLUGINS #include "pluginutils.h" #include "app.h" #include "geanyobject.h" #include "keybindings.h" #include "keybindingsprivate.h" #include "plugindata.h" #include "pluginprivate.h" #include "plugins.h" #include "support.h" #include "toolbar.h" #include "ui_utils.h" #include "utils.h" typedef struct { gpointer data; GDestroyNotify free_func; } PluginDocDataProxy; /** Returns the runtime API version Geany was compiled with. * * Unlike @ref GEANY_API_VERSION this version is the value of that * define at the time when Geany itself was compiled. This allows to * establish soft dependencies which are resolved at runtime depending * on Geany's API version. * * @return Geany's API version * @since 1.30 (API 231) **/ GEANY_API_SYMBOL gint geany_api_version(void) { return GEANY_API_VERSION; } /** Inserts a toolbar item before the Quit button, or after the previous plugin toolbar item. * A separator is added on the first call to this function, and will be shown when @a item is * shown; hidden when @a item is hidden. * @note You should still destroy @a item yourself, usually in @ref plugin_cleanup(). * @param plugin Must be @ref geany_plugin. * @param item The item to add. */ GEANY_API_SYMBOL void plugin_add_toolbar_item(GeanyPlugin *plugin, GtkToolItem *item) { GtkToolbar *toolbar = GTK_TOOLBAR(main_widgets.toolbar); gint pos; GeanyAutoSeparator *autosep; g_return_if_fail(plugin); autosep = &plugin->priv->toolbar_separator; if (!autosep->widget) { GtkToolItem *sep; pos = toolbar_get_insert_position(); sep = gtk_separator_tool_item_new(); gtk_toolbar_insert(toolbar, sep, pos); autosep->widget = GTK_WIDGET(sep); toolbar_item_ref(sep); } else { pos = gtk_toolbar_get_item_index(toolbar, GTK_TOOL_ITEM(autosep->widget)); g_return_if_fail(pos >= 0); } gtk_toolbar_insert(toolbar, item, pos + autosep->item_count + 1); toolbar_item_ref(item); /* hide the separator widget if there are no toolbar items showing for the plugin */ ui_auto_separator_add_ref(autosep, GTK_WIDGET(item)); } /** Ensures that a plugin's module (*.so) will never be unloaded. * This is necessary if you register new GTypes in your plugin, e.g. when using own classes * using the GObject system. * * @param plugin Must be @ref geany_plugin. * * @since 0.16 */ GEANY_API_SYMBOL void plugin_module_make_resident(GeanyPlugin *plugin) { g_return_if_fail(plugin); plugin_make_resident(plugin->priv); } /** @girskip * Connects a signal which will be disconnected on unloading the plugin, to prevent a possible segfault. * @param plugin Must be @ref geany_plugin. * @param object @nullable Object to connect to, or @c NULL when using @link pluginsignals.c Geany signals @endlink. * @param signal_name The name of the signal. For a list of available * signals, please see the @link pluginsignals.c Signal documentation @endlink. * @param after Set to @c TRUE to call your handler after the main signal handlers have been called * (if supported by @a signal_name). * @param callback The function to call when the signal is emitted. * @param user_data The user data passed to the signal handler. * @see plugin_callbacks. * * @warning Before version 1.25 (API < 218), * this should only be used on objects that outlive the plugin, never on * objects that will get destroyed before the plugin is unloaded. For objects * created and destroyed by the plugin, you can simply use @c g_signal_connect(), * since all handlers are disconnected when the object is destroyed anyway. * For objects that may or may not outlive the plugin (like @link GeanyEditor.sci * a document's @c ScintillaObject @endlink, which is destroyed when the document * is closed), you currently have to manually handle both situations, when the * plugin is unloaded before the object is destroyed (and then, you have to * disconnect the signal on @c plugin_cleanup()), and when the object is destroyed * during the plugin's lifetime (in which case you cannot and should not disconnect * manually in @c plugin_cleanup() since it already has been disconnected and the * object has been destroyed), and disconnect yourself or not as appropriate. * @note Since version 1.25 (API >= 218), the object lifetime is watched and so the above * restriction does not apply. However, for objects destroyed by the plugin, * @c g_signal_connect() is safe and has lower overhead. **/ GEANY_API_SYMBOL void plugin_signal_connect(GeanyPlugin *plugin, GObject *object, const gchar *signal_name, gboolean after, GCallback callback, gpointer user_data) { gulong id; SignalConnection sc; g_return_if_fail(plugin != NULL); g_return_if_fail(object == NULL || G_IS_OBJECT(object)); if (!object) object = geany_object; id = after ? g_signal_connect_after(object, signal_name, callback, user_data) : g_signal_connect(object, signal_name, callback, user_data); if (!plugin->priv->signal_ids) plugin->priv->signal_ids = g_array_new(FALSE, FALSE, sizeof(SignalConnection)); sc.object = object; sc.handler_id = id; g_array_append_val(plugin->priv->signal_ids, sc); /* watch the object lifetime to nuke our pointers to it */ plugin_watch_object(plugin->priv, object); } typedef struct PluginSourceData { Plugin *plugin; GList list_link; /* element of plugin->sources cointaining this GSource */ GSourceFunc function; gpointer user_data; } PluginSourceData; /* prepend psd->list_link to psd->plugin->sources */ static void psd_register(PluginSourceData *psd, GSource *source) { psd->list_link.data = source; psd->list_link.prev = NULL; psd->list_link.next = psd->plugin->sources; if (psd->list_link.next) psd->list_link.next->prev = &psd->list_link; psd->plugin->sources = &psd->list_link; } /* removes psd->list_link from psd->plugin->sources */ static void psd_unregister(PluginSourceData *psd) { if (psd->list_link.next) psd->list_link.next->prev = psd->list_link.prev; if (psd->list_link.prev) psd->list_link.prev->next = psd->list_link.next; else /* we were the first of the list, update the plugin->sources pointer */ psd->plugin->sources = psd->list_link.next; } static void on_plugin_source_destroy(gpointer data) { PluginSourceData *psd = data; psd_unregister(psd); g_slice_free1(sizeof *psd, psd); } static gboolean on_plugin_source_callback(gpointer data) { PluginSourceData *psd = data; return psd->function(psd->user_data); } /* adds the given source to the default GMainContext and to the list of sources to remove at plugin * unloading time */ static guint plugin_source_add(GeanyPlugin *plugin, GSource *source, GSourceFunc func, gpointer data) { guint id; PluginSourceData *psd = g_slice_alloc(sizeof *psd); psd->plugin = plugin->priv; psd->function = func; psd->user_data = data; g_source_set_callback(source, on_plugin_source_callback, psd, on_plugin_source_destroy); psd_register(psd, source); id = g_source_attach(source, NULL); g_source_unref(source); return id; } /** @girskip * Adds a GLib main loop timeout callback that will be removed when unloading the plugin, * preventing it to run after the plugin has been unloaded (which may lead to a segfault). * * @param plugin Must be @ref geany_plugin. * @param interval The time between calls to the function, in milliseconds. * @param function The function to call after the given timeout. * @param data The user data passed to the function. * @return the ID of the event source (you generally won't need it, or better use g_timeout_add() * directly if you want to manage this event source manually). * * @see g_timeout_add() * @since 0.21, plugin API 205. */ GEANY_API_SYMBOL guint plugin_timeout_add(GeanyPlugin *plugin, guint interval, GSourceFunc function, gpointer data) { return plugin_source_add(plugin, g_timeout_source_new(interval), function, data); } /** @girskip * Adds a GLib main loop timeout callback that will be removed when unloading the plugin, * preventing it to run after the plugin has been unloaded (which may lead to a segfault). * * @param plugin Must be @ref geany_plugin. * @param interval The time between calls to the function, in seconds. * @param function The function to call after the given timeout. * @param data The user data passed to the function. * @return the ID of the event source (you generally won't need it, or better use * g_timeout_add_seconds() directly if you want to manage this event source manually). * * @see g_timeout_add_seconds() * @since 0.21, plugin API 205. */ GEANY_API_SYMBOL guint plugin_timeout_add_seconds(GeanyPlugin *plugin, guint interval, GSourceFunc function, gpointer data) { return plugin_source_add(plugin, g_timeout_source_new_seconds(interval), function, data); } /** @girskip * Adds a GLib main loop IDLE callback that will be removed when unloading the plugin, preventing * it to run after the plugin has been unloaded (which may lead to a segfault). * * @param plugin Must be @ref geany_plugin. * @param function The function to call in IDLE time. * @param data The user data passed to the function. * @return the ID of the event source (you generally won't need it, or better use g_idle_add() * directly if you want to manage this event source manually). * * @see g_idle_add() * @since 0.21, plugin API 205. */ GEANY_API_SYMBOL guint plugin_idle_add(GeanyPlugin *plugin, GSourceFunc function, gpointer data) { return plugin_source_add(plugin, g_idle_source_new(), function, data); } /** @girskip * Sets up or resizes a keybinding group for the plugin. * You should then call keybindings_set_item() for each keybinding in the group. * @param plugin Must be @ref geany_plugin. * @param section_name Name of the section used for this group in the keybindings configuration file, i.e. @c "html_chars". * @param count Number of keybindings for the group. * @param callback @nullable Group callback, or @c NULL if you only want individual keybinding callbacks. * @return The plugin's keybinding group. * @since 0.19. **/ GEANY_API_SYMBOL GeanyKeyGroup *plugin_set_key_group(GeanyPlugin *plugin, const gchar *section_name, gsize count, GeanyKeyGroupCallback callback) { Plugin *priv = plugin->priv; priv->key_group = keybindings_set_group(priv->key_group, section_name, priv->info.name, count, callback); return priv->key_group; } /** Sets up or resizes a keybinding group for the plugin * * You should then call keybindings_set_item() or keybindings_set_item_full() for each * keybinding in the group. * @param plugin Must be @ref geany_plugin. * @param section_name Name of the section used for this group in the keybindings configuration file, i.e. @c "html_chars". * @param count Number of keybindings for the group. * @param cb @nullable New-style group callback, or @c NULL if you only want individual keybinding callbacks. * @param pdata Plugin specific data, passed to the group callback @a cb. * @param destroy_notify Function that is invoked to free the plugin data when not needed anymore. * @return @transfer{none} The plugin's keybinding group. * * @since 1.26 (API 226) * @see See keybindings_set_item * @see See keybindings_set_item_full **/ GEANY_API_SYMBOL GeanyKeyGroup *plugin_set_key_group_full(GeanyPlugin *plugin, const gchar *section_name, gsize count, GeanyKeyGroupFunc cb, gpointer pdata, GDestroyNotify destroy_notify) { GeanyKeyGroup *group; group = plugin_set_key_group(plugin, section_name, count, NULL); group->cb_func = cb; group->cb_data = pdata; group->cb_data_destroy = destroy_notify; return group; } static void on_pref_btn_clicked(gpointer btn, Plugin *p) { p->configure_single(main_widgets.window); } static GtkWidget *create_pref_page(Plugin *p, GtkWidget *dialog) { GtkWidget *page = NULL; /* some plugins don't have prefs */ if (p->cbs.configure) { page = p->cbs.configure(&p->public, GTK_DIALOG(dialog), p->cb_data); if (! GTK_IS_WIDGET(page)) { geany_debug("Invalid widget returned from plugin_configure() in plugin \"%s\"!", p->info.name); return NULL; } else { GtkWidget *align = gtk_alignment_new(0.5, 0.5, 1, 1); gtk_alignment_set_padding(GTK_ALIGNMENT(align), 6, 6, 6, 6); gtk_container_add(GTK_CONTAINER(align), page); page = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); gtk_box_pack_start(GTK_BOX(page), align, TRUE, TRUE, 0); } } else if (p->configure_single) { GtkWidget *align = gtk_alignment_new(0.5, 0.5, 0, 0); GtkWidget *btn; gtk_alignment_set_padding(GTK_ALIGNMENT(align), 6, 6, 6, 6); btn = gtk_button_new_from_stock(GTK_STOCK_PREFERENCES); g_signal_connect(btn, "clicked", G_CALLBACK(on_pref_btn_clicked), p); gtk_container_add(GTK_CONTAINER(align), btn); page = align; } return page; } /* multiple plugin configure dialog * current_plugin can be NULL */ static void configure_plugins(Plugin *current_plugin) { GtkWidget *dialog, *vbox, *nb; GList *node; gint cur_page = -1; dialog = gtk_dialog_new_with_buttons(_("Configure Plugins"), GTK_WINDOW(main_widgets.window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_APPLY, GTK_RESPONSE_APPLY, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_OK, NULL); gtk_widget_set_name(dialog, "GeanyDialog"); vbox = ui_dialog_vbox_new(GTK_DIALOG(dialog)); nb = gtk_notebook_new(); gtk_notebook_set_scrollable(GTK_NOTEBOOK(nb), TRUE); gtk_box_pack_start(GTK_BOX(vbox), nb, TRUE, TRUE, 0); foreach_list(node, active_plugin_list) { Plugin *p = node->data; GtkWidget *page = create_pref_page(p, dialog); if (page) { GtkWidget *label = gtk_label_new(p->info.name); gint n = gtk_notebook_append_page(GTK_NOTEBOOK(nb), page, label); if (p == current_plugin) cur_page = n; } } if (gtk_notebook_get_n_pages(GTK_NOTEBOOK(nb))) { gtk_widget_show_all(vbox); if (cur_page >= 0) gtk_notebook_set_current_page(GTK_NOTEBOOK(nb), cur_page); /* run the dialog */ while (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_APPLY); } else utils_beep(); gtk_widget_destroy(dialog); } /** Shows the plugin's configure dialog. * The plugin must implement one of the plugin_configure() or plugin_configure_single() symbols. * @param plugin Must be @ref geany_plugin. * @since 0.19. */ /* if NULL, show all plugins */ GEANY_API_SYMBOL void plugin_show_configure(GeanyPlugin *plugin) { Plugin *p; if (!plugin) { configure_plugins(NULL); return; } p = plugin->priv; if (p->cbs.configure) configure_plugins(p); else { g_return_if_fail(p->configure_single); p->configure_single(main_widgets.window); } } struct BuilderConnectData { gpointer user_data; GeanyPlugin *plugin; }; static void connect_plugin_signals(GtkBuilder *builder, GObject *object, const gchar *signal_name, const gchar *handler_name, GObject *connect_object, GConnectFlags flags, gpointer user_data) { gpointer symbol = NULL; struct BuilderConnectData *data = user_data; symbol = plugin_get_module_symbol(data->plugin->priv, handler_name); plugin_signal_connect(data->plugin, object, signal_name, FALSE, G_CALLBACK(symbol) /*ub?*/, data->user_data); } /** * Allows auto-connecting Glade/GtkBuilder signals in plugins. * * When a plugin uses GtkBuilder to load some UI from file/string, * the gtk_builder_connect_signals() function is unable to automatically * connect to the plugin's signal handlers. A plugin could itself use * the gtk_builder_connect_signals_full() function to automatically * connect to the signal handler functions by loading it's GModule * and retrieving pointers to the handler functions, but rather than * each plugin having to do that, this function handles it automatically. * * @code * ... * GeanyPlugin *geany_plugin; * * G_MODULE_EXPORT void * myplugin_button_clicked(GtkButton *button, gpointer user_data) * { * g_print("Button pressed\n"); * } * * void plugin_init(GeanyData *data) * { * GtkBuilder *builder = gtk_builder_new(); * gtk_builder_add_from_file(builder, "gui.glade", NULL); * plugin_builder_connect_signals(geany_plugin, builder, NULL); * ... * } * @endcode * * @note It's important that you prefix your callback handlers with * a plugin-specific prefix to avoid clashing with other plugins since * the function symbols will be exported process-wide. * * @param plugin Must be @ref geany_plugin. * @param builder The GtkBuilder to connect signals with. * @param user_data User data to pass to the connected signal handlers. * * @since 1.24, plugin API 217. */ GEANY_API_SYMBOL void plugin_builder_connect_signals(GeanyPlugin *plugin, GtkBuilder *builder, gpointer user_data) { struct BuilderConnectData data = { NULL }; g_return_if_fail(plugin != NULL && plugin->priv != NULL); g_return_if_fail(GTK_IS_BUILDER(builder)); data.user_data = user_data; data.plugin = plugin; gtk_builder_connect_signals_full(builder, connect_plugin_signals, &data); } /** Get the additional data that corresponds to the plugin. * * @param plugin The plugin provided by Geany * @return The data corresponding to the plugin or @c NULL if none set. * * @since 1.32 (API 234) * * @see geany_plugin_set_data() */ gpointer geany_plugin_get_data(const GeanyPlugin *plugin) { g_return_val_if_fail (plugin != NULL, NULL); g_return_val_if_fail (PLUGIN_LOADED_OK (plugin->priv), NULL); return plugin->priv->cb_data; } /** Add additional data that corresponds to the plugin. * * @p pdata is the pointer going to be passed to the individual plugin callbacks * of GeanyPlugin::funcs. When the plugin is cleaned up, @p free_func is invoked for the data, * which connects the data to the time the plugin is enabled. * * One intended use case is to set GObjects as data and have them destroyed automatically * by passing g_object_unref() as @a free_func, so that member functions can be used * for the @ref GeanyPluginFuncs (via wrappers) but you can set completely custom data. * * Be aware that this can only be called once and only by plugins registered via * @ref geany_plugin_register(). So-called legacy plugins cannot use this function. * * @note This function must not be called if the plugin was registered with * geany_plugin_register_full(). * * @param plugin The plugin provided by Geany * @param pdata The plugin's data to associate, must not be @c NULL * @param free_func The destroy notify * * @since 1.26 (API 225) */ GEANY_API_SYMBOL void geany_plugin_set_data(GeanyPlugin *plugin, gpointer pdata, GDestroyNotify free_func) { Plugin *p = plugin->priv; g_return_if_fail(PLUGIN_LOADED_OK(p)); /* Do not allow calling this only to set a notify. */ g_return_if_fail(pdata != NULL); /* The rationale to allow only setting the data once is the following: * In the future we want to support proxy plugins (which bind non-C plugins to * Geany's plugin api). These proxy plugins might need to own the data pointer * on behalf of the proxied plugin. However, if not, then the plugin should be * free to use it. This way we can make sure the plugin doesn't accidentally * trash its proxy. * * Better a more limited API now that can be opened up later than a potentially * wrong one that can only be replaced by another one. */ if (p->cb_data != NULL || p->cb_data_destroy != NULL) { if (PLUGIN_HAS_LOAD_DATA(p)) g_warning("Invalid call to %s(), geany_plugin_register_full() was used. Ignored!\n", G_STRFUNC); else g_warning("Double call to %s(), ignored!", G_STRFUNC); return; } p->cb_data = pdata; p->cb_data_destroy = free_func; } static void plugin_doc_data_proxy_free(gpointer pdata) { PluginDocDataProxy *prox = pdata; if (prox != NULL) { if (prox->free_func) prox->free_func(prox->data); g_slice_free(PluginDocDataProxy, prox); } } /** * Retrieve plugin-specific data attached to a document. * * @param plugin The plugin who attached the data. * @param doc The document which the data was attached to. * @param key The key name of the attached data. * * @return The attached data pointer or `NULL` if the key is not found * for the given plugin. * * @since 1.29 (Plugin API 228) * @see plugin_set_document_data plugin_set_document_data_full */ GEANY_API_SYMBOL gpointer plugin_get_document_data(struct GeanyPlugin *plugin, struct GeanyDocument *doc, const gchar *key) { gchar *real_key; PluginDocDataProxy *data; g_return_val_if_fail(plugin != NULL, NULL); g_return_val_if_fail(doc != NULL, NULL); g_return_val_if_fail(key != NULL && *key != '\0', NULL); real_key = g_strdup_printf("geany/plugins/%s/%s", plugin->info->name, key); data = document_get_data(doc, real_key); g_free(real_key); return (data != NULL) ? data->data : NULL; } /** * Attach plugin-specific data to a document. * * @param plugin The plugin attaching data to the document. * @param doc The document to attach the data to. * @param key The key name for the data. * @param data The pointer to attach to the document. * * @since 1.29 (Plugin API 228) * @see plugin_get_document_data plugin_set_document_data_full */ GEANY_API_SYMBOL void plugin_set_document_data(struct GeanyPlugin *plugin, struct GeanyDocument *doc, const gchar *key, gpointer data) { plugin_set_document_data_full(plugin, doc, key, data, NULL); } /** * Attach plugin-specific data and a free function to a document. * * This is useful for plugins who want to keep some additional data with * the document and even have it auto-released appropriately (see below). * * This is a simple example showing how a plugin might use this to * attach a string to each document and print it when the document is * saved: * * @code * void on_document_open(GObject *unused, GeanyDocument *doc, GeanyPlugin *plugin) * { * plugin_set_document_data_full(plugin, doc, "my-data", * g_strdup("some-data"), g_free); * } * * void on_document_save(GObject *unused, GeanyDocument *doc, GeanyPlugin *plugin) * { * const gchar *some_data = plugin_get_document_data(plugin, doc, "my-data"); * g_print("my-data: %s\n", some_data); * } * * gboolean plugin_init(GeanyPlugin *plugin, gpointer unused) * { * plugin_signal_connect(plugin, NULL, "document-open", TRUE, * G_CALLBACK(on_document_open), plugin); * plugin_signal_connect(plugin, NULL, "document-new", TRUE, * G_CALLBACK(on_document_open), plugin); * plugin_signal_connect(plugin, NULL, "document-save", TRUE, * G_CALLBACK(on_document_save), plugin); * return TRUE; * } * * void geany_load_module(GeanyPlugin *plugin) * { * // ... * plugin->funcs->init = plugin_init; * // ... * } * @endcode * * The @a free_func can be used to tie the lifetime of the data to that * of the @a doc and/or the @a plugin. The @a free_func will be called * in any of the following cases: * * - When a document is closed. * - When the plugin is unloaded. * - When the document data is set again using the same key. * * @param plugin The plugin attaching data to the document. * @param doc The document to attach the data to. * @param key The key name for the data. * @param data The pointer to attach to the document. * @param free_func The function to call with data when removed. * * @since 1.29 (Plugin API 228) * @see plugin_get_document_data plugin_set_document_data */ GEANY_API_SYMBOL void plugin_set_document_data_full(struct GeanyPlugin *plugin, struct GeanyDocument *doc, const gchar *key, gpointer data, GDestroyNotify free_func) { PluginDocDataProxy *prox; g_return_if_fail(plugin != NULL); g_return_if_fail(doc != NULL); g_return_if_fail(key != NULL); prox = g_slice_new(PluginDocDataProxy); if (prox != NULL) { gchar *real_key = g_strdup_printf("geany/plugins/%s/%s", plugin->info->name, key); prox->data = data; prox->free_func = free_func; document_set_data_full(doc, real_key, prox, plugin_doc_data_proxy_free); g_free(real_key); } } #endif geany-2.0/src/osx.h0000644000175000017500000000212614514252267011161 00000000000000/* * osx.h - this file is part of Geany, a fast and lightweight IDE * * Copyright 2015 The Geany contributors * * This program 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; either version 2 of the License, or * (at your option) any later version. * * This program 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef GEANY_OSX_H #define GEANY_OSX_H 1 #ifdef MAC_INTEGRATION #include G_BEGIN_DECLS void osx_ui_init(void); G_END_DECLS #endif /* MAC_INTEGRATION */ #endif /* GEANY_OSX_H */ geany-2.0/src/msgwindow.c0000644000175000017500000011172614514252267012370 00000000000000/* * msgwindow.c - this file is part of Geany, a fast and lightweight IDE * * Copyright 2005 The Geany contributors * * This program 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; either version 2 of the License, or * (at your option) any later version. * * This program 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /** * @file msgwindow.h * Message window functions (status, compiler, messages windows). * Also compiler error message parsing and grep file and line parsing. * * @see GeanyMainWidgets::message_window_notebook to append a new notebook page. **/ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include "msgwindow.h" #include "build.h" #include "document.h" #include "callbacks.h" #include "filetypes.h" #include "keybindings.h" #include "main.h" #include "navqueue.h" #include "prefs.h" #include "support.h" #include "ui_utils.h" #include "utils.h" #include "vte.h" #include #include #include #include /* used for parse_file_line */ typedef struct { const gchar *string; /* line data */ const gchar *pattern; /* pattern to split the error message into some fields */ guint min_fields; /* used to detect errors after parsing */ guint line_idx; /* idx of the field where the line is */ gint file_idx; /* idx of the field where the filename is or -1 */ } ParseData; MessageWindow msgwindow; enum { MSG_COL_LINE = 0, MSG_COL_DOC_ID, MSG_COL_COLOR, MSG_COL_STRING, MSG_COL_COUNT }; enum { COMPILER_COL_COLOR = 0, COMPILER_COL_STRING, COMPILER_COL_COUNT }; static GdkColor color_error = {0, 0xFFFF, 0, 0}; static GdkColor color_context = {0, 0x7FFF, 0, 0}; static GdkColor color_message = {0, 0, 0, 0xD000}; static void prepare_msg_tree_view(void); static void prepare_status_tree_view(void); static void prepare_compiler_tree_view(void); static GtkWidget *create_message_popup_menu(gint type); static gboolean on_msgwin_button_press_event(GtkWidget *widget, GdkEventButton *event, gpointer user_data); static void on_scribble_populate(GtkTextView *textview, GtkMenu *arg1, gpointer user_data); void msgwin_show_hide_tabs(void) { ui_widget_show_hide(gtk_widget_get_parent(msgwindow.tree_status), interface_prefs.msgwin_status_visible); ui_widget_show_hide(gtk_widget_get_parent(msgwindow.tree_compiler), interface_prefs.msgwin_compiler_visible); ui_widget_show_hide(gtk_widget_get_parent(msgwindow.tree_msg), interface_prefs.msgwin_messages_visible); ui_widget_show_hide(gtk_widget_get_parent(msgwindow.scribble), interface_prefs.msgwin_scribble_visible); } /** * Sets the Messages path for opening any parsed filenames without absolute path from message lines. * * @param messages_dir The directory. **/ GEANY_API_SYMBOL void msgwin_set_messages_dir(const gchar *messages_dir) { g_free(msgwindow.messages_dir); msgwindow.messages_dir = g_strdup(messages_dir); } static void load_color(const gchar *color_name, GdkColor *color) { GdkRGBA rgba_color; GtkWidgetPath *path = gtk_widget_path_new(); GtkStyleContext *ctx = gtk_style_context_new(); gtk_widget_path_append_type(path, GTK_TYPE_WINDOW); gtk_widget_path_iter_set_name(path, -1, color_name); gtk_style_context_set_screen(ctx, gdk_screen_get_default()); gtk_style_context_set_path(ctx, path); gtk_style_context_get_color(ctx, gtk_style_context_get_state(ctx), &rgba_color); color->red = 0xffff * rgba_color.red; color->green = 0xffff * rgba_color.green; color->blue = 0xffff * rgba_color.blue; gtk_widget_path_unref(path); g_object_unref(ctx); } void msgwin_init(void) { msgwindow.notebook = ui_lookup_widget(main_widgets.window, "notebook_info"); msgwindow.tree_status = ui_lookup_widget(main_widgets.window, "treeview3"); msgwindow.tree_msg = ui_lookup_widget(main_widgets.window, "treeview4"); msgwindow.tree_compiler = ui_lookup_widget(main_widgets.window, "treeview5"); msgwindow.scribble = ui_lookup_widget(main_widgets.window, "textview_scribble"); msgwindow.messages_dir = NULL; prepare_status_tree_view(); prepare_msg_tree_view(); prepare_compiler_tree_view(); msgwindow.popup_status_menu = create_message_popup_menu(MSG_STATUS); msgwindow.popup_msg_menu = create_message_popup_menu(MSG_MESSAGE); msgwindow.popup_compiler_menu = create_message_popup_menu(MSG_COMPILER); ui_widget_modify_font_from_string(msgwindow.scribble, interface_prefs.msgwin_font); g_signal_connect(msgwindow.scribble, "populate-popup", G_CALLBACK(on_scribble_populate), NULL); load_color("geany-compiler-error", &color_error); load_color("geany-compiler-context", &color_context); load_color("geany-compiler-message", &color_message); } void msgwin_finalize(void) { g_free(msgwindow.messages_dir); } static gboolean on_msgwin_key_press_event(GtkWidget *widget, GdkEventKey *event, gpointer data) { gboolean enter_or_return = ui_is_keyval_enter_or_return(event->keyval); if (enter_or_return || event->keyval == GDK_KEY_space) { switch (GPOINTER_TO_INT(data)) { case MSG_COMPILER: { /* key press in the compiler treeview */ msgwin_goto_compiler_file_line(enter_or_return); break; } case MSG_MESSAGE: { /* key press in the message treeview (results of 'Find usage') */ msgwin_goto_messages_file_line(enter_or_return); break; } } } return FALSE; } /* does some preparing things to the status message list widget */ static void prepare_status_tree_view(void) { GtkCellRenderer *renderer; GtkTreeViewColumn *column; msgwindow.store_status = gtk_list_store_new(1, G_TYPE_STRING); gtk_tree_view_set_model(GTK_TREE_VIEW(msgwindow.tree_status), GTK_TREE_MODEL(msgwindow.store_status)); g_object_unref(msgwindow.store_status); renderer = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes(_("Status messages"), renderer, "text", 0, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(msgwindow.tree_status), column); gtk_tree_view_set_enable_search(GTK_TREE_VIEW(msgwindow.tree_status), FALSE); ui_widget_modify_font_from_string(msgwindow.tree_status, interface_prefs.msgwin_font); g_signal_connect(msgwindow.tree_status, "button-press-event", G_CALLBACK(on_msgwin_button_press_event), GINT_TO_POINTER(MSG_STATUS)); } /* does some preparing things to the message list widget * (currently used for showing results of 'Find usage') */ static void prepare_msg_tree_view(void) { GtkCellRenderer *renderer; GtkTreeViewColumn *column; GtkTreeSelection *selection; /* line, doc id, fg, str */ msgwindow.store_msg = gtk_list_store_new(MSG_COL_COUNT, G_TYPE_INT, G_TYPE_UINT, GDK_TYPE_COLOR, G_TYPE_STRING); gtk_tree_view_set_model(GTK_TREE_VIEW(msgwindow.tree_msg), GTK_TREE_MODEL(msgwindow.store_msg)); g_object_unref(msgwindow.store_msg); renderer = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes(NULL, renderer, "foreground-gdk", MSG_COL_COLOR, "text", MSG_COL_STRING, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(msgwindow.tree_msg), column); gtk_tree_view_set_enable_search(GTK_TREE_VIEW(msgwindow.tree_msg), FALSE); ui_widget_modify_font_from_string(msgwindow.tree_msg, interface_prefs.msgwin_font); /* use button-release-event so the selection has changed * (connect_after button-press-event doesn't work) */ g_signal_connect(msgwindow.tree_msg, "button-release-event", G_CALLBACK(on_msgwin_button_press_event), GINT_TO_POINTER(MSG_MESSAGE)); /* for double-clicking only, after the first release */ g_signal_connect(msgwindow.tree_msg, "button-press-event", G_CALLBACK(on_msgwin_button_press_event), GINT_TO_POINTER(MSG_MESSAGE)); g_signal_connect(msgwindow.tree_msg, "key-press-event", G_CALLBACK(on_msgwin_key_press_event), GINT_TO_POINTER(MSG_MESSAGE)); /* selection handling */ selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(msgwindow.tree_msg)); gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE); /*g_signal_connect(selection, "changed",G_CALLBACK(on_msg_tree_selection_changed), NULL);*/ } /* does some preparing things to the compiler list widget */ static void prepare_compiler_tree_view(void) { GtkCellRenderer *renderer; GtkTreeViewColumn *column; GtkTreeSelection *selection; msgwindow.store_compiler = gtk_list_store_new(COMPILER_COL_COUNT, GDK_TYPE_COLOR, G_TYPE_STRING); gtk_tree_view_set_model(GTK_TREE_VIEW(msgwindow.tree_compiler), GTK_TREE_MODEL(msgwindow.store_compiler)); g_object_unref(msgwindow.store_compiler); renderer = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes(NULL, renderer, "foreground-gdk", COMPILER_COL_COLOR, "text", COMPILER_COL_STRING, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(msgwindow.tree_compiler), column); gtk_tree_view_set_enable_search(GTK_TREE_VIEW(msgwindow.tree_compiler), FALSE); ui_widget_modify_font_from_string(msgwindow.tree_compiler, interface_prefs.msgwin_font); /* use button-release-event so the selection has changed * (connect_after button-press-event doesn't work) */ g_signal_connect(msgwindow.tree_compiler, "button-release-event", G_CALLBACK(on_msgwin_button_press_event), GINT_TO_POINTER(MSG_COMPILER)); /* for double-clicking only, after the first release */ g_signal_connect(msgwindow.tree_compiler, "button-press-event", G_CALLBACK(on_msgwin_button_press_event), GINT_TO_POINTER(MSG_COMPILER)); g_signal_connect(msgwindow.tree_compiler, "key-press-event", G_CALLBACK(on_msgwin_key_press_event), GINT_TO_POINTER(MSG_COMPILER)); /* selection handling */ selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(msgwindow.tree_compiler)); gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE); /*g_signal_connect(selection, "changed", G_CALLBACK(on_msg_tree_selection_changed), NULL);*/ } static const GdkColor *get_color(gint msg_color) { switch (msg_color) { case COLOR_RED: return &color_error; case COLOR_DARK_RED: return &color_context; case COLOR_BLUE: return &color_message; default: return NULL; } } /** * Adds a formatted message in the compiler tab treeview in the messages window. * * @param msg_color A color to be used for the text. It must be an element of #MsgColors. * @param format @c printf()-style format string. * @param ... Arguments for the @c format string. * * @see msgwin_compiler_add_string() * * @since 0.16 **/ GEANY_API_SYMBOL void msgwin_compiler_add(gint msg_color, const gchar *format, ...) { gchar *string; va_list args; va_start(args, format); string = g_strdup_vprintf(format, args); va_end(args); msgwin_compiler_add_string(msg_color, string); g_free(string); } /** * Adds a new message in the compiler tab treeview in the messages window. * * @param msg_color A color to be used for the text. It must be an element of #MsgColors. * @param msg Compiler message to be added. * * @see msgwin_compiler_add() * * @since 1.34 (API 236) **/ GEANY_API_SYMBOL void msgwin_compiler_add_string(gint msg_color, const gchar *msg) { GtkTreeIter iter; const GdkColor *color = get_color(msg_color); gchar *utf8_msg; if (! g_utf8_validate(msg, -1, NULL)) utf8_msg = utils_get_utf8_from_locale(msg); else utf8_msg = (gchar *) msg; gtk_list_store_append(msgwindow.store_compiler, &iter); gtk_list_store_set(msgwindow.store_compiler, &iter, COMPILER_COL_COLOR, color, COMPILER_COL_STRING, utf8_msg, -1); if (ui_prefs.msgwindow_visible && interface_prefs.compiler_tab_autoscroll) { GtkTreePath *path = gtk_tree_model_get_path( gtk_tree_view_get_model(GTK_TREE_VIEW(msgwindow.tree_compiler)), &iter); gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(msgwindow.tree_compiler), path, NULL, TRUE, 0.5, 0.5); gtk_tree_path_free(path); } if (utf8_msg != msg) g_free(utf8_msg); } void msgwin_show_hide(gboolean show) { ui_prefs.msgwindow_visible = show; ignore_callback = TRUE; gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM(ui_lookup_widget(main_widgets.window, "menu_show_messages_window1")), show); ignore_callback = FALSE; ui_widget_show_hide(main_widgets.message_window_notebook, show); /* set the input focus back to the editor */ keybindings_send_command(GEANY_KEY_GROUP_FOCUS, GEANY_KEYS_FOCUS_EDITOR); } /** * Adds a formatted message in the messages tab treeview in the messages window. * * If @a line and @a doc are set, clicking on this line jumps into the file * which is specified by @a doc into the line specified with @a line. * * @param msg_color A color to be used for the text. It must be an element of #MsgColors. * @param line The document's line where the message belongs to. Set to @c -1 to ignore. * @param doc @nullable The document. Set to @c NULL to ignore. * @param format @c printf()-style format string. * @param ... Arguments for the @c format string. * * @see msgwin_msg_add_string() * * @since 0.16 **/ GEANY_API_SYMBOL void msgwin_msg_add(gint msg_color, gint line, GeanyDocument *doc, const gchar *format, ...) { gchar *string; va_list args; va_start(args, format); string = g_strdup_vprintf(format, args); va_end(args); msgwin_msg_add_string(msg_color, line, doc, string); g_free(string); } /** * Adds a new message in the messages tab treeview in the messages window. * * If @a line and @a doc are set, clicking on this line jumps into the * file which is specified by @a doc into the line specified with @a line. * * @param msg_color A color to be used for the text. It must be an element of #MsgColors. * @param line The document's line where the message belongs to. Set to @c -1 to ignore. * @param doc @nullable The document. Set to @c NULL to ignore. * @param string Message to be added. * * @see msgwin_msg_add() * * @since 1.34 (API 236) **/ GEANY_API_SYMBOL void msgwin_msg_add_string(gint msg_color, gint line, GeanyDocument *doc, const gchar *string) { GtkTreeIter iter; const GdkColor *color = get_color(msg_color); gchar *tmp; gsize len; gchar *utf8_msg; if (! ui_prefs.msgwindow_visible) msgwin_show_hide(TRUE); /* work around a strange problem when adding very long lines(greater than 4000 bytes) * cut the string to a maximum of 1024 bytes and discard the rest */ /* TODO: find the real cause for the display problem / if it is GtkTreeView file a bug report */ len = strlen(string); if (len > 1024) tmp = g_strndup(string, 1024); else tmp = g_strdup(string); if (! g_utf8_validate(tmp, -1, NULL)) utf8_msg = utils_get_utf8_from_locale(tmp); else utf8_msg = tmp; gtk_list_store_append(msgwindow.store_msg, &iter); gtk_list_store_set(msgwindow.store_msg, &iter, MSG_COL_LINE, line, MSG_COL_DOC_ID, doc ? doc->id : 0, MSG_COL_COLOR, color, MSG_COL_STRING, utf8_msg, -1); g_free(tmp); if (utf8_msg != tmp) g_free(utf8_msg); } /** * Logs a new status message *without* setting the status bar. * * Use @ref ui_set_statusbar() to display text on the statusbar. * * @param string Status message to be logged. * * @see msgwin_status_add() * * @since 1.34 (API 236) **/ GEANY_API_SYMBOL void msgwin_status_add_string(const gchar *string) { GtkTreeIter iter; gchar *statusmsg, *time_str; /* add a timestamp to status messages */ time_str = utils_get_current_time_string(FALSE); statusmsg = g_strconcat(time_str, ": ", string, NULL); g_free(time_str); /* add message to Status window */ gtk_list_store_append(msgwindow.store_status, &iter); gtk_list_store_set(msgwindow.store_status, &iter, 0, statusmsg, -1); g_free(statusmsg); if (G_LIKELY(main_status.main_window_realized)) { GtkTreePath *path = gtk_tree_model_get_path(gtk_tree_view_get_model(GTK_TREE_VIEW(msgwindow.tree_status)), &iter); gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(msgwindow.tree_status), path, NULL, FALSE, 0.0, 0.0); if (prefs.switch_to_status) gtk_notebook_set_current_page(GTK_NOTEBOOK(msgwindow.notebook), MSG_STATUS); gtk_tree_path_free(path); } } /** * Logs a formatted status message *without* setting the status bar. * * Use @ref ui_set_statusbar() to display text on the statusbar. * * @param format @c printf()-style format string. * @param ... Arguments for the @c format string. * * @see msgwin_status_add_string() * * @since 0.12 **/ GEANY_API_SYMBOL void msgwin_status_add(const gchar *format, ...) { gchar *string; va_list args; va_start(args, format); string = g_strdup_vprintf(format, args); va_end(args); msgwin_status_add_string(string); g_free(string); } static void on_message_treeview_clear_activate(GtkMenuItem *menuitem, gpointer user_data) { gint tabnum = GPOINTER_TO_INT(user_data); msgwin_clear_tab(tabnum); } static void on_compiler_treeview_copy_activate(GtkMenuItem *menuitem, gpointer user_data) { GtkWidget *tv = NULL; GtkTreeSelection *selection; GtkTreeModel *model; GtkTreeIter iter; gint str_idx = COMPILER_COL_STRING; switch (GPOINTER_TO_INT(user_data)) { case MSG_STATUS: tv = msgwindow.tree_status; str_idx = 0; break; case MSG_COMPILER: tv = msgwindow.tree_compiler; break; case MSG_MESSAGE: tv = msgwindow.tree_msg; str_idx = MSG_COL_STRING; break; } selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tv)); if (gtk_tree_selection_get_selected(selection, &model, &iter)) { gchar *string; gtk_tree_model_get(model, &iter, str_idx, &string, -1); if (!EMPTY(string)) { gtk_clipboard_set_text(gtk_clipboard_get(gdk_atom_intern("CLIPBOARD", FALSE)), string, -1); } g_free(string); } } static void on_compiler_treeview_copy_all_activate(GtkMenuItem *menuitem, gpointer user_data) { GtkListStore *store = msgwindow.store_compiler; GtkTreeIter iter; GString *str = g_string_new(""); gint str_idx = COMPILER_COL_STRING; gboolean valid; switch (GPOINTER_TO_INT(user_data)) { case MSG_STATUS: store = msgwindow.store_status; str_idx = 0; break; case MSG_COMPILER: /* default values */ break; case MSG_MESSAGE: store = msgwindow.store_msg; str_idx = MSG_COL_STRING; break; } /* walk through the list and copy every line into a string */ valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter); while (valid) { gchar *line; gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, str_idx, &line, -1); if (!EMPTY(line)) { g_string_append(str, line); g_string_append_c(str, '\n'); } g_free(line); valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &iter); } /* copy the string into the clipboard */ if (str->len > 0) { gtk_clipboard_set_text( gtk_clipboard_get(gdk_atom_intern("CLIPBOARD", FALSE)), str->str, str->len); } g_string_free(str, TRUE); } static void on_hide_message_window(GtkMenuItem *menuitem, gpointer user_data) { msgwin_show_hide(FALSE); } static GtkWidget *create_message_popup_menu(gint type) { GtkWidget *message_popup_menu, *clear, *copy, *copy_all, *image; message_popup_menu = gtk_menu_new(); clear = gtk_image_menu_item_new_from_stock(GTK_STOCK_CLEAR, NULL); gtk_widget_show(clear); gtk_container_add(GTK_CONTAINER(message_popup_menu), clear); g_signal_connect(clear, "activate", G_CALLBACK(on_message_treeview_clear_activate), GINT_TO_POINTER(type)); copy = gtk_image_menu_item_new_with_mnemonic(_("C_opy")); gtk_widget_show(copy); gtk_container_add(GTK_CONTAINER(message_popup_menu), copy); image = gtk_image_new_from_stock(GTK_STOCK_COPY, GTK_ICON_SIZE_MENU); gtk_widget_show(image); gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(copy), image); g_signal_connect(copy, "activate", G_CALLBACK(on_compiler_treeview_copy_activate), GINT_TO_POINTER(type)); copy_all = gtk_image_menu_item_new_with_mnemonic(_("Copy _All")); gtk_widget_show(copy_all); gtk_container_add(GTK_CONTAINER(message_popup_menu), copy_all); image = gtk_image_new_from_stock(GTK_STOCK_COPY, GTK_ICON_SIZE_MENU); gtk_widget_show(image); gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(copy_all), image); g_signal_connect(copy_all, "activate", G_CALLBACK(on_compiler_treeview_copy_all_activate), GINT_TO_POINTER(type)); msgwin_menu_add_common_items(GTK_MENU(message_popup_menu)); return message_popup_menu; } static void on_scribble_populate(GtkTextView *textview, GtkMenu *arg1, gpointer user_data) { msgwin_menu_add_common_items(arg1); } /* Menu items that should be on all message window popup menus */ void msgwin_menu_add_common_items(GtkMenu *menu) { GtkWidget *item; item = gtk_separator_menu_item_new(); gtk_widget_show(item); gtk_container_add(GTK_CONTAINER(menu), item); item = gtk_menu_item_new_with_mnemonic(_("_Hide Message Window")); gtk_widget_show(item); gtk_container_add(GTK_CONTAINER(menu), item); g_signal_connect(item, "activate", G_CALLBACK(on_hide_message_window), NULL); } /* look back up from the current path and find the directory we came from */ static gboolean find_prev_build_dir(GtkTreePath *cur, GtkTreeModel *model, gchar **prefix) { GtkTreeIter iter; *prefix = NULL; while (gtk_tree_path_prev(cur)) { if (gtk_tree_model_get_iter(model, &iter, cur)) { gchar *string; gtk_tree_model_get(model, &iter, COMPILER_COL_STRING, &string, -1); if (string != NULL && build_parse_make_dir(string, prefix)) { g_free(string); return TRUE; } g_free(string); } } return FALSE; } static gboolean goto_compiler_file_line(const gchar *fname, gint line, gboolean focus_editor) { gboolean ret = FALSE; gchar *filename; if (!fname || line <= -1) return FALSE; filename = utils_get_locale_from_utf8(fname); /* If the path doesn't exist, try the current document. * This happens when we receive build messages in the wrong order - after the * 'Leaving directory' messages */ if (!g_file_test(filename, G_FILE_TEST_EXISTS)) { gchar *cur_dir = utils_get_current_file_dir_utf8(); gchar *name; if (cur_dir) { /* we let the user know we couldn't find the parsed filename from the message window */ SETPTR(cur_dir, utils_get_locale_from_utf8(cur_dir)); name = g_path_get_basename(filename); SETPTR(name, g_build_path(G_DIR_SEPARATOR_S, cur_dir, name, NULL)); g_free(cur_dir); if (g_file_test(name, G_FILE_TEST_EXISTS)) { ui_set_statusbar(FALSE, _("Could not find file '%s' - trying the current document path."), fname); SETPTR(filename, name); } else g_free(name); } } { gchar *utf8_filename = utils_get_utf8_from_locale(filename); GeanyDocument *doc = document_find_by_filename(utf8_filename); GeanyDocument *old_doc = document_get_current(); g_free(utf8_filename); if (doc == NULL) /* file not already open */ doc = document_open_file(filename, FALSE, NULL, NULL); if (doc != NULL) { if (! doc->changed && editor_prefs.use_indicators) /* if modified, line may be wrong */ editor_indicator_set_on_line(doc->editor, GEANY_INDICATOR_ERROR, line - 1); ret = navqueue_goto_line(old_doc, doc, line); if (ret && focus_editor) gtk_widget_grab_focus(GTK_WIDGET(doc->editor->sci)); ret = TRUE; } } g_free(filename); return ret; } gboolean msgwin_goto_compiler_file_line(gboolean focus_editor) { GtkTreeIter iter; GtkTreeModel *model; GtkTreeSelection *selection; gchar *string; GdkColor *color; selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(msgwindow.tree_compiler)); if (gtk_tree_selection_get_selected(selection, &model, &iter)) { /* if the item is not coloured red, it's not an error line */ gtk_tree_model_get(model, &iter, COMPILER_COL_COLOR, &color, -1); if (color == NULL || ! gdk_color_equal(color, &color_error)) { if (color != NULL) gdk_color_free(color); return FALSE; } gdk_color_free(color); gtk_tree_model_get(model, &iter, COMPILER_COL_STRING, &string, -1); if (string != NULL) { gint line; gchar *filename, *dir; GtkTreePath *path; gboolean ret; path = gtk_tree_model_get_path(model, &iter); find_prev_build_dir(path, model, &dir); gtk_tree_path_free(path); msgwin_parse_compiler_error_line(string, dir, &filename, &line); g_free(string); g_free(dir); ret = goto_compiler_file_line(filename, line, focus_editor); g_free(filename); return ret; } } return FALSE; } static void make_absolute(gchar **filename, const gchar *dir) { guint skip_dot_slash = 0; /* number of characters to skip at the beginning of the filename */ if (*filename == NULL) return; /* skip some characters at the beginning of the filename, at the moment only "./" * can be extended if other "trash" is known */ if (strncmp(*filename, "./", 2) == 0) skip_dot_slash = 2; /* add directory */ if (! utils_is_absolute_path(*filename)) SETPTR(*filename, g_build_filename(dir, *filename + skip_dot_slash, NULL)); } /* try to parse the file and line number where the error occurred described in line * and when something useful is found, it stores the line number in *line and the * relevant file with the error in *filename. * *line will be -1 if no error was found in string. * *filename must be freed unless it is NULL. */ static void parse_file_line(ParseData *data, gchar **filename, gint *line) { gchar *end = NULL; gchar **fields; *filename = NULL; *line = -1; g_return_if_fail(data->string != NULL); fields = g_strsplit_set(data->string, data->pattern, data->min_fields); /* parse the line */ if (g_strv_length(fields) < data->min_fields) { g_strfreev(fields); return; } *line = strtol(fields[data->line_idx], &end, 10); /* if the line could not be read, line is 0 and an error occurred, so we leave */ if (fields[data->line_idx] == end) { g_strfreev(fields); return; } /* let's stop here if there is no filename in the error message */ if (data->file_idx == -1) { /* we have no filename in the error message, so take the current one and hope it's correct */ GeanyDocument *doc = document_get_current(); if (doc != NULL) *filename = g_strdup(doc->file_name); g_strfreev(fields); return; } *filename = g_strdup(fields[data->file_idx]); g_strfreev(fields); } static void parse_compiler_error_line(const gchar *string, gchar **filename, gint *line) { ParseData data = {NULL, NULL, 0, 0, 0}; data.string = string; switch (build_info.file_type_id) { case GEANY_FILETYPES_PHP: { /* Parse error: parse error, unexpected T_CASE in brace_bug.php on line 3 * Parse error: syntax error, unexpected T_LNUMBER, expecting T_FUNCTION in bob.php on line 16 */ gchar *tmp = strstr(string, " in "); if (tmp != NULL) { data.string = tmp; data.pattern = " "; data.min_fields = 6; data.line_idx = 5; data.file_idx = 2; } else { data.pattern = " "; data.min_fields = 11; data.line_idx = 10; data.file_idx = 7; } break; } case GEANY_FILETYPES_PERL: { /* syntax error at test.pl line 7, near "{ */ data.pattern = " "; data.min_fields = 6; data.line_idx = 5; data.file_idx = 3; break; } /* the error output of python and tcl equals */ case GEANY_FILETYPES_TCL: case GEANY_FILETYPES_PYTHON: { /* File "HyperArch.py", line 37, in ? * (file "clrdial.tcl" line 12) * */ if (strstr(string, " line ") != NULL) { /* Tcl and old Python format (<= Python 2.5) */ data.pattern = " \""; data.min_fields = 6; data.line_idx = 5; data.file_idx = 2; } else { /* SyntaxError: ('invalid syntax', ('sender.py', 149, 20, ' ...')) * (used since Python 2.6) */ data.pattern = ",'"; data.min_fields = 8; data.line_idx = 6; data.file_idx = 4; } break; } case GEANY_FILETYPES_BASIC: case GEANY_FILETYPES_PASCAL: case GEANY_FILETYPES_CS: { /* getdrive.bas(52) error 18: Syntax error in '? GetAllDrives' * bandit.pas(149,3) Fatal: Syntax error, ";" expected but "ELSE" found */ data.pattern = "("; data.min_fields = 2; data.line_idx = 1; data.file_idx = 0; break; } case GEANY_FILETYPES_D: { /* GNU D compiler front-end, gdc * gantry.d:18: variable gantry.main.c reference to auto class must be auto * warning - gantry.d:20: statement is not reachable * Digital Mars dmd compiler * warning - pi.d(118): implicit conversion of expression (digit) of type int ... * gantry.d(18): variable gantry.main.c reference to auto class must be auto */ if (strncmp(string, "warning - ", 10) == 0) { data.pattern = " (:"; data.min_fields = 4; data.line_idx = 3; data.file_idx = 2; } else { data.pattern = "(:"; data.min_fields = 2; data.line_idx = 1; data.file_idx = 0; } break; } case GEANY_FILETYPES_HTML: { /* line 78 column 7 - Warning: missing '>' for end of tag */ data.pattern = " "; data.min_fields = 4; data.line_idx = 1; data.file_idx = -1; break; } /* All GNU gcc-like error messages */ case GEANY_FILETYPES_C: case GEANY_FILETYPES_CPP: case GEANY_FILETYPES_RUBY: case GEANY_FILETYPES_JAVA: /* only gcc is supported, I don't know any other C(++) compilers and their error messages * empty.h:4: Warnung: type defaults to `int' in declaration of `foo' * empty.c:21: error: conflicting types for `foo' * Only parse file and line, so that linker errors will also work (with -g) */ case GEANY_FILETYPES_F77: case GEANY_FILETYPES_FORTRAN: case GEANY_FILETYPES_LATEX: /* ./kommtechnik_2b.tex:18: Emergency stop. */ case GEANY_FILETYPES_MAKE: /* Assume makefile is building with gcc */ case GEANY_FILETYPES_NONE: default: /* The default is a GNU gcc type error */ { if (build_info.file_type_id == GEANY_FILETYPES_JAVA && strncmp(string, "[javac]", 7) == 0) { /* Java Apache Ant. * [javac] :: */ data.pattern = " :"; data.min_fields = 4; data.line_idx = 2; data.file_idx = 1; break; } /* don't accidentally find libtool versions x:y:x and think it is a file name */ if (strstr(string, "libtool --mode=link") == NULL) { data.pattern = ":"; data.min_fields = 3; data.line_idx = 1; data.file_idx = 0; break; } } } if (data.pattern != NULL) parse_file_line(&data, filename, line); } /* try to parse the file and line number where the error occurred described in string * and when something useful is found, it stores the line number in *line and the * relevant file with the error in *filename. * *line will be -1 if no error was found in string. * *filename must be freed unless it is NULL. */ void msgwin_parse_compiler_error_line(const gchar *string, const gchar *dir, gchar **filename, gint *line) { GeanyFiletype *ft; gchar *trimmed_string, *utf8_dir; *filename = NULL; *line = -1; if (G_UNLIKELY(string == NULL)) return; if (dir == NULL) utf8_dir = utils_get_utf8_from_locale(build_info.dir); else utf8_dir = g_strdup(dir); g_return_if_fail(utf8_dir != NULL); trimmed_string = g_strdup(string); g_strchug(trimmed_string); /* remove possible leading whitespace */ ft = filetypes[build_info.file_type_id]; /* try parsing with a custom regex */ if (!filetypes_parse_error_message(ft, trimmed_string, filename, line)) { /* fallback to default old-style parsing */ parse_compiler_error_line(trimmed_string, filename, line); } make_absolute(filename, utf8_dir); g_free(trimmed_string); g_free(utf8_dir); } /* Tries to parse strings of the file:line style, allowing line field to be missing * * filename is filled with the filename, should be freed * * line is filled with the line number or -1 */ static void msgwin_parse_generic_line(const gchar *string, gchar **filename, gint *line) { gchar **fields; gboolean incertain = TRUE; /* whether we're reasonably certain of the result */ *filename = NULL; *line = -1; fields = g_strsplit(string, ":", 2); /* extract the filename */ if (fields[0] != NULL) { *filename = utils_get_locale_from_utf8(fields[0]); if (msgwindow.messages_dir != NULL) make_absolute(filename, msgwindow.messages_dir); /* now the line */ if (fields[1] != NULL) { gchar *end; *line = strtol(fields[1], &end, 10); if (end == fields[1]) *line = -1; else if (*end == ':' || g_ascii_isspace(*end)) { /* if we have a blank or a separator right after the number, assume we really got a * filename (it's a grep-like syntax) */ incertain = FALSE; } } /* if we aren't sure we got a supposedly correct filename, check it */ if (incertain && ! g_file_test(*filename, G_FILE_TEST_EXISTS)) { SETPTR(*filename, NULL); *line = -1; } } g_strfreev(fields); } gboolean msgwin_goto_messages_file_line(gboolean focus_editor) { GtkTreeIter iter; GtkTreeModel *model; GtkTreeSelection *selection; gboolean ret = FALSE; selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(msgwindow.tree_msg)); if (gtk_tree_selection_get_selected(selection, &model, &iter)) { gint line; guint id; gchar *string; GeanyDocument *doc; GeanyDocument *old_doc = document_get_current(); gtk_tree_model_get(model, &iter, MSG_COL_LINE, &line, MSG_COL_DOC_ID, &id, MSG_COL_STRING, &string, -1); if (line >= 0 && id > 0) { /* check doc is still open */ doc = document_find_by_id(id); if (!doc) { ui_set_statusbar(FALSE, _("The document has been closed.")); utils_beep(); } else { ret = navqueue_goto_line(old_doc, doc, line); if (ret && focus_editor) gtk_widget_grab_focus(GTK_WIDGET(doc->editor->sci)); } } else if (line < 0 && string != NULL) { gchar *filename; /* try with a file:line parsing */ msgwin_parse_generic_line(string, &filename, &line); if (filename != NULL) { /* use document_open_file to find an already open file, or open it in place */ doc = document_open_file(filename, FALSE, NULL, NULL); if (doc != NULL) { ret = (line < 0) ? TRUE : navqueue_goto_line(old_doc, doc, line); if (ret && focus_editor) gtk_widget_grab_focus(GTK_WIDGET(doc->editor->sci)); } } g_free(filename); } g_free(string); } return ret; } static gboolean on_msgwin_button_press_event(GtkWidget *widget, GdkEventButton *event, gpointer user_data) { /* user_data might be NULL, GPOINTER_TO_INT returns 0 if called with NULL */ gboolean double_click = event->type == GDK_2BUTTON_PRESS; if (event->button == 1 && (event->type == GDK_BUTTON_RELEASE || double_click)) { switch (GPOINTER_TO_INT(user_data)) { case MSG_COMPILER: { /* mouse click in the compiler treeview */ msgwin_goto_compiler_file_line(double_click); break; } case MSG_MESSAGE: { /* mouse click in the message treeview (results of 'Find usage') */ msgwin_goto_messages_file_line(double_click); break; } } return double_click; /* TRUE prevents message window re-focusing */ } if (event->button == 3) { /* popupmenu to hide or clear the active treeview */ switch (GPOINTER_TO_INT(user_data)) { case MSG_STATUS: { gtk_menu_popup_at_pointer(GTK_MENU(msgwindow.popup_status_menu), (GdkEvent *) event); break; } case MSG_MESSAGE: { gtk_menu_popup_at_pointer(GTK_MENU(msgwindow.popup_msg_menu), (GdkEvent *) event); break; } case MSG_COMPILER: { gtk_menu_popup_at_pointer(GTK_MENU(msgwindow.popup_compiler_menu), (GdkEvent *) event); break; } } } return FALSE; } /** * Switches to the given notebook tab of the messages window. * * The messages window is shown if it was previously hidden and @a show is set to @c TRUE. * * @param tabnum An index of a tab in the messages window. Valid values are * all elements of #MessageWindowTabNum. * @param show Whether to show the messages window at all if it was hidden before. * * @since 0.15 **/ GEANY_API_SYMBOL void msgwin_switch_tab(gint tabnum, gboolean show) { GtkWidget *widget = NULL; /* widget to focus */ switch (tabnum) { case MSG_SCRATCH: widget = msgwindow.scribble; break; case MSG_COMPILER: widget = msgwindow.tree_compiler; break; case MSG_STATUS: widget = msgwindow.tree_status; break; case MSG_MESSAGE: widget = msgwindow.tree_msg; break; #ifdef HAVE_VTE case MSG_VTE: widget = (vte_info.have_vte) ? vte_config.vte : NULL; break; #endif default: break; } /* the msgwin must be visible before we switch to the VTE page so that * the font settings are applied on realization */ if (show) msgwin_show_hide(TRUE); gtk_notebook_set_current_page(GTK_NOTEBOOK(msgwindow.notebook), tabnum); if (show && widget) gtk_widget_grab_focus(widget); } /** * Removes all messages from a tab specified by @a tabnum in the messages window. * * @param tabnum An index of a tab in the messages window which should be cleared. * Valid values are @c MSG_STATUS, @c MSG_COMPILER and @c MSG_MESSAGE. * * @since 0.15 **/ GEANY_API_SYMBOL void msgwin_clear_tab(gint tabnum) { GtkListStore *store = NULL; switch (tabnum) { case MSG_MESSAGE: store = msgwindow.store_msg; break; case MSG_COMPILER: gtk_list_store_clear(msgwindow.store_compiler); build_menu_update(NULL); /* update next error items */ return; case MSG_STATUS: store = msgwindow.store_status; break; default: return; } if (store == NULL) return; gtk_list_store_clear(store); } geany-2.0/src/keyfile.c0000644000175000017500000016440314514252267012002 00000000000000/* * keyfile.c - this file is part of Geany, a fast and lightweight IDE * * Copyright 2005 The Geany contributors * * This program 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; either version 2 of the License, or * (at your option) any later version. * * This program 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /* * geany.conf preferences file loading and saving. */ /* * Session file format: * filename_xx=pos;filetype UID;read only;Eencoding;use_tabs;auto_indent;line_wrapping;filename */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include "keyfile.h" #include "app.h" #include "build.h" #include "document.h" #include "encodings.h" #include "encodingsprivate.h" #include "filetypes.h" #include "geanyobject.h" #include "main.h" #include "msgwindow.h" #include "prefs.h" #include "printing.h" #include "project.h" #include "sciwrappers.h" #include "sidebar.h" #include "socket.h" #include "stash.h" #include "support.h" #include "symbols.h" #include "templates.h" #include "toolbar.h" #include "ui_utils.h" #include "utils.h" #include "vte.h" #include #include #include #ifdef HAVE_VTE #include #include #include #endif /* define the configuration filenames */ #define PREFS_FILE "geany.conf" #define SESSION_FILE "session.conf" /* some default settings which are used at the very first start of Geany to fill * the configuration file */ #define GEANY_MAX_SYMBOLLIST_HEIGHT 10 #define GEANY_MIN_SYMBOLLIST_CHARS 4 #define GEANY_MSGWIN_HEIGHT 208 #define GEANY_DISK_CHECK_TIMEOUT 30 #define GEANY_DEFAULT_TOOLS_MAKE "make" #ifdef G_OS_WIN32 #define GEANY_DEFAULT_TOOLS_TERMINAL "cmd.exe /Q /C %c" #elif defined(__APPLE__) #define GEANY_DEFAULT_TOOLS_TERMINAL "open -a terminal %c" #else #define GEANY_DEFAULT_TOOLS_TERMINAL "xterm -e \"/bin/sh %c\"" #endif #ifdef __APPLE__ #define GEANY_DEFAULT_TOOLS_BROWSER "open -a safari" #define GEANY_DEFAULT_FONT_SYMBOL_LIST "Helvetica Medium 12" #define GEANY_DEFAULT_FONT_MSG_WINDOW "Menlo Medium 12" #define GEANY_DEFAULT_FONT_EDITOR "Menlo Medium 12" #else /* Browser chosen by GTK */ #define GEANY_DEFAULT_TOOLS_BROWSER "" #define GEANY_DEFAULT_FONT_SYMBOL_LIST "Sans 9" #define GEANY_DEFAULT_FONT_MSG_WINDOW "Monospace 9" #define GEANY_DEFAULT_FONT_EDITOR "Monospace 10" #endif #define GEANY_DEFAULT_TOOLS_PRINTCMD "lpr" #define GEANY_DEFAULT_TOOLS_GREP "grep" #define GEANY_DEFAULT_MRU_LENGTH 10 #define GEANY_TOGGLE_MARK "~ " #define GEANY_MAX_AUTOCOMPLETE_WORDS 30 #define GEANY_MAX_SYMBOLS_UPDATE_FREQ 250 #define GEANY_DEFAULT_FILETYPE_REGEX "-\\*-\\s*([^\\s]+)\\s*-\\*-" static gchar *scribble_text = NULL; static gint scribble_pos = -1; static GPtrArray *default_session_files = NULL; static gint session_notebook_page; static gint hpan_position; static gint vpan_position; static const gchar atomic_file_saving_key[] = "use_atomic_file_saving"; typedef enum { PREFS, SESSION, MAX_PAYLOAD } ConfigPayload; /* Fallback only used when loading config. Saving config should always write the real file. */ static gchar *get_keyfile_for_payload(ConfigPayload payload) { static gboolean logged; gchar *file; switch (payload) { case PREFS: file = g_build_filename(app->configdir, PREFS_FILE, NULL); if (! g_file_test(file, G_FILE_TEST_IS_REGULAR)) { /* config file does not (yet) exist, so try to load a global config * file which may be created by distributors */ g_message("No user config file found, trying to use global configuration."); g_free(file); file = g_build_filename(app->datadir, PREFS_FILE, NULL); } return file; case SESSION: file = g_build_filename(app->configdir, SESSION_FILE, NULL); if (! g_file_test(file, G_FILE_TEST_IS_REGULAR)) { if (!logged) { g_message("No user session file found, trying to use configuration file."); logged = TRUE; } g_free(file); file = g_build_filename(app->configdir, PREFS_FILE, NULL); } return file; case MAX_PAYLOAD: g_assert_not_reached(); } return NULL; } static GPtrArray *keyfile_groups[MAX_PAYLOAD]; GPtrArray *pref_groups; static struct { gint number_ft_menu_items; gint number_non_ft_menu_items; gint number_exec_menu_items; } build_menu_prefs; /* The group will be free'd on quitting. * @param for_prefs_dialog is whether the group also has Prefs dialog items. */ void configuration_add_pref_group(struct StashGroup *group, gboolean for_prefs_dialog) { g_ptr_array_add(keyfile_groups[PREFS], group); if (for_prefs_dialog) g_ptr_array_add(pref_groups, group); } /* The group will be free'd on quitting. * prefix can be NULL to use group name */ void configuration_add_various_pref_group(struct StashGroup *group, const gchar *prefix) { configuration_add_pref_group(group, TRUE); stash_group_set_various(group, TRUE, prefix); } /* The group will be free'd on quitting. * * @a for_prefs_dialog is typically @c FALSE as session configuration is not * well suited for the Preferences dialog. Probably only existing prefs that * migrated to session data should set this to @c TRUE. * * @param for_prefs_dialog is whether the group also has Prefs dialog items. */ void configuration_add_session_group(struct StashGroup *group, gboolean for_prefs_dialog) { g_ptr_array_add(keyfile_groups[SESSION], group); if (for_prefs_dialog) g_ptr_array_add(pref_groups, group); } static void init_pref_groups(void) { StashGroup *group; group = stash_group_new(PACKAGE); configuration_add_pref_group(group, TRUE); stash_group_add_entry(group, &prefs.default_open_path, "default_open_path", "", "startup_path_entry"); stash_group_add_toggle_button(group, &file_prefs.cmdline_new_files, "cmdline_new_files", TRUE, "check_cmdline_new_files"); stash_group_add_toggle_button(group, &interface_prefs.notebook_double_click_hides_widgets, "notebook_double_click_hides_widgets", FALSE, "check_double_click_hides_widgets"); stash_group_add_toggle_button(group, &file_prefs.tab_close_switch_to_mru, "tab_close_switch_to_mru", FALSE, "check_tab_close_switch_to_mru"); stash_group_add_integer(group, &interface_prefs.tab_pos_sidebar, "tab_pos_sidebar", GTK_POS_TOP); stash_group_add_integer(group, &interface_prefs.openfiles_path_mode, "openfiles_path_mode", -1); stash_group_add_radio_buttons(group, &interface_prefs.sidebar_pos, "sidebar_pos", GTK_POS_LEFT, "radio_sidebar_left", GTK_POS_LEFT, "radio_sidebar_right", GTK_POS_RIGHT, NULL); stash_group_add_radio_buttons(group, &interface_prefs.symbols_sort_mode, "symbols_sort_mode", SYMBOLS_SORT_BY_NAME, "radio_symbols_sort_by_name", SYMBOLS_SORT_BY_NAME, "radio_symbols_sort_by_appearance", SYMBOLS_SORT_BY_APPEARANCE, NULL); stash_group_add_radio_buttons(group, &interface_prefs.msgwin_orientation, "msgwin_orientation", GTK_ORIENTATION_VERTICAL, "radio_msgwin_vertical", GTK_ORIENTATION_VERTICAL, "radio_msgwin_horizontal", GTK_ORIENTATION_HORIZONTAL, NULL); /* editor display */ stash_group_add_toggle_button(group, &interface_prefs.highlighting_invert_all, "highlighting_invert_all", FALSE, "check_highlighting_invert"); stash_group_add_toggle_button(group, &search_prefs.use_current_word, "pref_main_search_use_current_word", TRUE, "check_search_use_current_word"); /* editor */ stash_group_add_toggle_button(group, &editor_prefs.indentation->detect_type, "check_detect_indent", FALSE, "check_detect_indent_type"); stash_group_add_toggle_button(group, &editor_prefs.indentation->detect_width, "detect_indent_width", FALSE, "check_detect_indent_width"); stash_group_add_toggle_button(group, &editor_prefs.use_tab_to_indent, "use_tab_to_indent", TRUE, "check_tab_key_indents"); stash_group_add_toggle_button(group, &editor_prefs.backspace_unindent, "backspace_unindent", TRUE, "check_backspace_unindent"); stash_group_add_spin_button_integer(group, &editor_prefs.indentation->width, "pref_editor_tab_width", 4, "spin_indent_width"); stash_group_add_combo_box(group, (gint*)(void*)&editor_prefs.indentation->auto_indent_mode, "indent_mode", GEANY_AUTOINDENT_CURRENTCHARS, "combo_auto_indent_mode"); stash_group_add_radio_buttons(group, (gint*)(void*)&editor_prefs.indentation->type, "indent_type", GEANY_INDENT_TYPE_TABS, "radio_indent_spaces", GEANY_INDENT_TYPE_SPACES, "radio_indent_tabs", GEANY_INDENT_TYPE_TABS, "radio_indent_both", GEANY_INDENT_TYPE_BOTH, NULL); stash_group_add_radio_buttons(group, (gint*)(void*)&editor_prefs.show_virtual_space, "virtualspace", GEANY_VIRTUAL_SPACE_SELECTION, "radio_virtualspace_disabled", GEANY_VIRTUAL_SPACE_DISABLED, "radio_virtualspace_selection", GEANY_VIRTUAL_SPACE_SELECTION, "radio_virtualspace_always", GEANY_VIRTUAL_SPACE_ALWAYS, NULL); stash_group_add_toggle_button(group, &editor_prefs.change_history_markers, "change_history_markers", FALSE, "check_change_history_markers"); stash_group_add_toggle_button(group, &editor_prefs.change_history_indicators, "change_history_indicators", FALSE, "check_change_history_indicators"); stash_group_add_toggle_button(group, &editor_prefs.autocomplete_doc_words, "autocomplete_doc_words", FALSE, "check_autocomplete_doc_words"); stash_group_add_toggle_button(group, &editor_prefs.completion_drops_rest_of_word, "completion_drops_rest_of_word", FALSE, "check_completion_drops_rest_of_word"); stash_group_add_spin_button_integer(group, (gint*)&editor_prefs.autocompletion_max_entries, "autocompletion_max_entries", GEANY_MAX_AUTOCOMPLETE_WORDS, "spin_autocompletion_max_entries"); stash_group_add_spin_button_integer(group, (gint*)&editor_prefs.autocompletion_update_freq, "autocompletion_update_freq", GEANY_MAX_SYMBOLS_UPDATE_FREQ, "spin_symbol_update_freq"); stash_group_add_string(group, &editor_prefs.color_scheme, "color_scheme", NULL); stash_group_add_spin_button_integer(group, &editor_prefs.scroll_lines_around_cursor, "scroll_lines_around_cursor", 0, "spin_scroll_lines_around_cursor"); /* files */ stash_group_add_spin_button_integer(group, (gint*)&file_prefs.mru_length, "mru_length", GEANY_DEFAULT_MRU_LENGTH, "spin_mru"); stash_group_add_spin_button_integer(group, &file_prefs.disk_check_timeout, "disk_check_timeout", GEANY_DISK_CHECK_TIMEOUT, "spin_disk_check"); /* various geany prefs */ group = stash_group_new(PACKAGE); configuration_add_various_pref_group(group, "editor"); stash_group_add_boolean(group, &editor_prefs.show_scrollbars, "show_editor_scrollbars", TRUE); stash_group_add_boolean(group, &editor_prefs.brace_match_ltgt, "brace_match_ltgt", FALSE); stash_group_add_boolean(group, &editor_prefs.use_gtk_word_boundaries, "use_gtk_word_boundaries", TRUE); stash_group_add_boolean(group, &editor_prefs.complete_snippets_whilst_editing, "complete_snippets_whilst_editing", FALSE); /* for backwards-compatibility */ stash_group_add_integer(group, &editor_prefs.indentation->hard_tab_width, "indent_hard_tab_width", 8); stash_group_add_integer(group, &editor_prefs.ime_interaction, "editor_ime_interaction", SC_IME_WINDOWED); group = stash_group_new(PACKAGE); configuration_add_various_pref_group(group, "files"); stash_group_add_boolean(group, &file_prefs.use_safe_file_saving, atomic_file_saving_key, FALSE); stash_group_add_boolean(group, &file_prefs.gio_unsafe_save_backup, "gio_unsafe_save_backup", FALSE); stash_group_add_boolean(group, &file_prefs.use_gio_unsafe_file_saving, "use_gio_unsafe_file_saving", TRUE); stash_group_add_boolean(group, &file_prefs.keep_edit_history_on_reload, "keep_edit_history_on_reload", TRUE); stash_group_add_boolean(group, &file_prefs.show_keep_edit_history_on_reload_msg, "show_keep_edit_history_on_reload_msg", TRUE); stash_group_add_boolean(group, &file_prefs.reload_clean_doc_on_file_change, "reload_clean_doc_on_file_change", FALSE); stash_group_add_boolean(group, &file_prefs.save_config_on_file_change, "save_config_on_file_change", TRUE); stash_group_add_string(group, &file_prefs.extract_filetype_regex, "extract_filetype_regex", GEANY_DEFAULT_FILETYPE_REGEX); stash_group_add_boolean(group, &ui_prefs.allow_always_save, "allow_always_save", FALSE); group = stash_group_new(PACKAGE); configuration_add_various_pref_group(group, "search"); stash_group_add_integer(group, (gint*)&search_prefs.find_selection_type, "find_selection_type", GEANY_FIND_SEL_CURRENT_WORD); stash_group_add_boolean(group, &search_prefs.replace_and_find_by_default, "replace_and_find_by_default", TRUE); group = stash_group_new(PACKAGE); configuration_add_various_pref_group(group, "socket"); #ifdef G_OS_WIN32 stash_group_add_integer(group, (gint*)&prefs.socket_remote_cmd_port, "socket_remote_cmd_port", SOCKET_WINDOWS_REMOTE_CMD_PORT); #endif #ifdef HAVE_VTE /* various VTE prefs. */ group = stash_group_new("VTE"); configuration_add_various_pref_group(group, "terminal"); stash_group_add_string(group, &vte_config.send_cmd_prefix, "send_cmd_prefix", ""); stash_group_add_boolean(group, &vte_config.send_selection_unsafe, "send_selection_unsafe", FALSE); #endif /* Note: Interface-related various prefs are in ui_init_prefs() */ /* various build-menu prefs */ // Warning: don't move PACKAGE group name items here group = stash_group_new("build-menu"); configuration_add_various_pref_group(group, "build"); stash_group_add_integer(group, &build_menu_prefs.number_ft_menu_items, "number_ft_menu_items", 0); stash_group_add_integer(group, &build_menu_prefs.number_non_ft_menu_items, "number_non_ft_menu_items", 0); stash_group_add_integer(group, &build_menu_prefs.number_exec_menu_items, "number_exec_menu_items", 0); } typedef enum SettingAction { SETTING_READ, SETTING_WRITE } SettingAction; static void settings_action(GKeyFile *config, SettingAction action, ConfigPayload payload) { guint i; StashGroup *group; foreach_ptr_array(group, i, keyfile_groups[payload]) { switch (action) { case SETTING_READ: stash_group_load_from_key_file(group, config); break; case SETTING_WRITE: stash_group_save_to_key_file(group, config); break; } } } static void save_recent_files(GKeyFile *config, GQueue *queue, gchar const *key) { gchar **recent_files = g_new0(gchar*, file_prefs.mru_length + 1); guint i; for (i = 0; i < file_prefs.mru_length; i++) { if (! g_queue_is_empty(queue)) { /* copy the values, this is necessary when this function is called from the * preferences dialog or when quitting is canceled to keep the queue intact */ recent_files[i] = g_strdup(g_queue_peek_nth(queue, i)); } else { recent_files[i] = NULL; break; } } /* There is a bug in GTK 2.6 g_key_file_set_string_list, we must NULL terminate. */ recent_files[file_prefs.mru_length] = NULL; g_key_file_set_string_list(config, "files", key, (const gchar**)recent_files, file_prefs.mru_length); g_strfreev(recent_files); } static gchar *get_session_file_string(GeanyDocument *doc) { gchar *fname; gchar *locale_filename; gchar *escaped_filename; GeanyFiletype *ft = doc->file_type; if (ft == NULL) /* can happen when saving a new file when quitting */ ft = filetypes[GEANY_FILETYPES_NONE]; locale_filename = utils_get_locale_from_utf8(doc->file_name); escaped_filename = g_uri_escape_string(locale_filename, NULL, TRUE); fname = g_strdup_printf("%d;%s;%d;E%s;%d;%d;%d;%s;%d;%d", sci_get_current_position(doc->editor->sci), ft->name, doc->readonly, doc->encoding, doc->editor->indent_type, doc->editor->auto_indent, doc->editor->line_wrapping, escaped_filename, doc->editor->line_breaking, doc->editor->indent_width); g_free(escaped_filename); g_free(locale_filename); return fname; } static void remove_session_files(GKeyFile *config) { gchar **ptr; gchar **keys = g_key_file_get_keys(config, "files", NULL, NULL); foreach_strv(ptr, keys) { if (g_str_has_prefix(*ptr, "FILE_NAME_")) g_key_file_remove_key(config, "files", *ptr, NULL); } g_strfreev(keys); } void configuration_save_session_files(GKeyFile *config) { gint npage; gchar entry[16]; guint i = 0, j = 0, max; npage = gtk_notebook_get_current_page(GTK_NOTEBOOK(main_widgets.notebook)); g_key_file_set_integer(config, "files", "current_page", npage); // clear existing entries first as they might not all be overwritten remove_session_files(config); /* store the filenames in the notebook tab order to reopen them the next time */ max = gtk_notebook_get_n_pages(GTK_NOTEBOOK(main_widgets.notebook)); for (i = 0; i < max; i++) { GeanyDocument *doc = document_get_from_page(i); if (doc != NULL && doc->real_path != NULL) { gchar *fname; g_snprintf(entry, sizeof(entry), "FILE_NAME_%d", j); fname = get_session_file_string(doc); g_key_file_set_string(config, "files", entry, fname); g_free(fname); j++; } } #ifdef HAVE_VTE if (vte_info.have_vte) { vte_get_working_directory(); /* refresh vte_info.dir */ g_key_file_set_string(config, "VTE", "last_dir", vte_info.dir); } #endif } static void save_dialog_prefs(GKeyFile *config) { /* Some of the key names are not consistent, but this is for backwards compatibility */ /* general */ g_key_file_set_boolean(config, PACKAGE, "pref_main_load_session", prefs.load_session); g_key_file_set_boolean(config, PACKAGE, "pref_main_project_file_in_basedir", project_prefs.project_file_in_basedir); g_key_file_set_boolean(config, PACKAGE, "pref_main_save_winpos", prefs.save_winpos); g_key_file_set_boolean(config, PACKAGE, "pref_main_save_wingeom", prefs.save_wingeom); g_key_file_set_boolean(config, PACKAGE, "pref_main_confirm_exit", prefs.confirm_exit); g_key_file_set_boolean(config, PACKAGE, "pref_main_suppress_status_messages", prefs.suppress_status_messages); g_key_file_set_boolean(config, PACKAGE, "switch_msgwin_pages", prefs.switch_to_status); g_key_file_set_boolean(config, PACKAGE, "beep_on_errors", prefs.beep_on_errors); g_key_file_set_boolean(config, PACKAGE, "auto_focus", prefs.auto_focus); /* interface */ g_key_file_set_boolean(config, PACKAGE, "sidebar_symbol_visible", interface_prefs.sidebar_symbol_visible); g_key_file_set_boolean(config, PACKAGE, "sidebar_openfiles_visible", interface_prefs.sidebar_openfiles_visible); g_key_file_set_string(config, PACKAGE, "editor_font", interface_prefs.editor_font); g_key_file_set_string(config, PACKAGE, "tagbar_font", interface_prefs.tagbar_font); g_key_file_set_string(config, PACKAGE, "msgwin_font", interface_prefs.msgwin_font); g_key_file_set_boolean(config, PACKAGE, "show_notebook_tabs", interface_prefs.show_notebook_tabs); g_key_file_set_boolean(config, PACKAGE, "show_tab_cross", file_prefs.show_tab_cross); g_key_file_set_boolean(config, PACKAGE, "tab_order_ltr", file_prefs.tab_order_ltr); g_key_file_set_boolean(config, PACKAGE, "tab_order_beside", file_prefs.tab_order_beside); g_key_file_set_integer(config, PACKAGE, "tab_pos_editor", interface_prefs.tab_pos_editor); g_key_file_set_integer(config, PACKAGE, "tab_pos_msgwin", interface_prefs.tab_pos_msgwin); g_key_file_set_integer(config, PACKAGE, "tab_label_length", interface_prefs.tab_label_len); /* display */ g_key_file_set_boolean(config, PACKAGE, "show_indent_guide", editor_prefs.show_indent_guide); g_key_file_set_boolean(config, PACKAGE, "show_white_space", editor_prefs.show_white_space); g_key_file_set_boolean(config, PACKAGE, "show_line_endings", editor_prefs.show_line_endings); g_key_file_set_boolean(config, PACKAGE, "show_line_endings_only_when_differ", editor_prefs.show_line_endings_only_when_differ); g_key_file_set_boolean(config, PACKAGE, "show_markers_margin", editor_prefs.show_markers_margin); g_key_file_set_boolean(config, PACKAGE, "show_linenumber_margin", editor_prefs.show_linenumber_margin); g_key_file_set_boolean(config, PACKAGE, "long_line_enabled", editor_prefs.long_line_enabled); g_key_file_set_integer(config, PACKAGE, "long_line_type", editor_prefs.long_line_type); g_key_file_set_integer(config, PACKAGE, "long_line_column", editor_prefs.long_line_column); g_key_file_set_string(config, PACKAGE, "long_line_color", editor_prefs.long_line_color); /* editor */ g_key_file_set_integer(config, PACKAGE, "symbolcompletion_max_height", editor_prefs.symbolcompletion_max_height); g_key_file_set_integer(config, PACKAGE, "symbolcompletion_min_chars", editor_prefs.symbolcompletion_min_chars); g_key_file_set_boolean(config, PACKAGE, "use_folding", editor_prefs.folding); g_key_file_set_boolean(config, PACKAGE, "unfold_all_children", editor_prefs.unfold_all_children); g_key_file_set_boolean(config, PACKAGE, "use_indicators", editor_prefs.use_indicators); g_key_file_set_boolean(config, PACKAGE, "line_wrapping", editor_prefs.line_wrapping); g_key_file_set_boolean(config, PACKAGE, "auto_close_xml_tags", editor_prefs.auto_close_xml_tags); g_key_file_set_boolean(config, PACKAGE, "complete_snippets", editor_prefs.complete_snippets); g_key_file_set_boolean(config, PACKAGE, "auto_complete_symbols", editor_prefs.auto_complete_symbols); g_key_file_set_boolean(config, PACKAGE, "pref_editor_disable_dnd", editor_prefs.disable_dnd); g_key_file_set_boolean(config, PACKAGE, "pref_editor_smart_home_key", editor_prefs.smart_home_key); g_key_file_set_boolean(config, PACKAGE, "pref_editor_newline_strip", editor_prefs.newline_strip); g_key_file_set_integer(config, PACKAGE, "line_break_column", editor_prefs.line_break_column); g_key_file_set_boolean(config, PACKAGE, "auto_continue_multiline", editor_prefs.auto_continue_multiline); g_key_file_set_string(config, PACKAGE, "comment_toggle_mark", editor_prefs.comment_toggle_mark); g_key_file_set_boolean(config, PACKAGE, "scroll_stop_at_last_line", editor_prefs.scroll_stop_at_last_line); g_key_file_set_integer(config, PACKAGE, "autoclose_chars", editor_prefs.autoclose_chars); /* files */ g_key_file_set_string(config, PACKAGE, "pref_editor_default_new_encoding", encodings[file_prefs.default_new_encoding].charset); if (file_prefs.default_open_encoding == -1) g_key_file_set_string(config, PACKAGE, "pref_editor_default_open_encoding", "none"); else g_key_file_set_string(config, PACKAGE, "pref_editor_default_open_encoding", encodings[file_prefs.default_open_encoding].charset); g_key_file_set_integer(config, PACKAGE, "default_eol_character", file_prefs.default_eol_character); g_key_file_set_boolean(config, PACKAGE, "pref_editor_new_line", file_prefs.final_new_line); g_key_file_set_boolean(config, PACKAGE, "pref_editor_ensure_convert_line_endings", file_prefs.ensure_convert_new_lines); g_key_file_set_boolean(config, PACKAGE, "pref_editor_replace_tabs", file_prefs.replace_tabs); g_key_file_set_boolean(config, PACKAGE, "pref_editor_trail_space", file_prefs.strip_trailing_spaces); /* toolbar */ g_key_file_set_boolean(config, PACKAGE, "pref_toolbar_show", toolbar_prefs.visible); g_key_file_set_boolean(config, PACKAGE, "pref_toolbar_append_to_menu", toolbar_prefs.append_to_menu); g_key_file_set_boolean(config, PACKAGE, "pref_toolbar_use_gtk_default_style", toolbar_prefs.use_gtk_default_style); g_key_file_set_boolean(config, PACKAGE, "pref_toolbar_use_gtk_default_icon", toolbar_prefs.use_gtk_default_icon); g_key_file_set_integer(config, PACKAGE, "pref_toolbar_icon_style", toolbar_prefs.icon_style); g_key_file_set_integer(config, PACKAGE, "pref_toolbar_icon_size", toolbar_prefs.icon_size); /* templates */ g_key_file_set_string(config, PACKAGE, "pref_template_developer", template_prefs.developer); g_key_file_set_string(config, PACKAGE, "pref_template_company", template_prefs.company); g_key_file_set_string(config, PACKAGE, "pref_template_mail", template_prefs.mail); g_key_file_set_string(config, PACKAGE, "pref_template_initial", template_prefs.initials); g_key_file_set_string(config, PACKAGE, "pref_template_version", template_prefs.version); g_key_file_set_string(config, PACKAGE, "pref_template_year", template_prefs.year_format); g_key_file_set_string(config, PACKAGE, "pref_template_date", template_prefs.date_format); g_key_file_set_string(config, PACKAGE, "pref_template_datetime", template_prefs.datetime_format); /* tools settings */ g_key_file_set_string(config, "tools", "terminal_cmd", tool_prefs.term_cmd ? tool_prefs.term_cmd : ""); g_key_file_set_string(config, "tools", "browser_cmd", tool_prefs.browser_cmd ? tool_prefs.browser_cmd : ""); g_key_file_set_string(config, "tools", "grep_cmd", tool_prefs.grep_cmd ? tool_prefs.grep_cmd : ""); g_key_file_set_string(config, PACKAGE, "context_action_cmd", tool_prefs.context_action_cmd); /* build menu */ build_save_menu(config, NULL, GEANY_BCS_PREF); /* printing */ g_key_file_set_string(config, "printing", "print_cmd", printing_prefs.external_print_cmd ? printing_prefs.external_print_cmd : ""); g_key_file_set_boolean(config, "printing", "use_gtk_printing", printing_prefs.use_gtk_printing); g_key_file_set_boolean(config, "printing", "print_line_numbers", printing_prefs.print_line_numbers); g_key_file_set_boolean(config, "printing", "print_page_numbers", printing_prefs.print_page_numbers); g_key_file_set_boolean(config, "printing", "print_page_header", printing_prefs.print_page_header); g_key_file_set_boolean(config, "printing", "page_header_basename", printing_prefs.page_header_basename); g_key_file_set_string(config, "printing", "page_header_datefmt", printing_prefs.page_header_datefmt); /* VTE */ #ifdef HAVE_VTE g_key_file_set_boolean(config, "VTE", "load_vte", vte_info.load_vte); if (vte_info.have_vte) { VteConfig *vc = &vte_config; gchar *tmp_string; g_key_file_set_string(config, "VTE", "font", vc->font); g_key_file_set_boolean(config, "VTE", "scroll_on_key", vc->scroll_on_key); g_key_file_set_boolean(config, "VTE", "scroll_on_out", vc->scroll_on_out); g_key_file_set_boolean(config, "VTE", "enable_bash_keys", vc->enable_bash_keys); g_key_file_set_boolean(config, "VTE", "ignore_menu_bar_accel", vc->ignore_menu_bar_accel); g_key_file_set_boolean(config, "VTE", "follow_path", vc->follow_path); g_key_file_set_boolean(config, "VTE", "run_in_vte", vc->run_in_vte); g_key_file_set_boolean(config, "VTE", "skip_run_script", vc->skip_run_script); g_key_file_set_boolean(config, "VTE", "cursor_blinks", vc->cursor_blinks); g_key_file_set_integer(config, "VTE", "scrollback_lines", vc->scrollback_lines); g_key_file_set_string(config, "VTE", "font", vc->font); g_key_file_set_string(config, "VTE", "shell", vc->shell); tmp_string = utils_get_hex_from_color(&vc->colour_fore); g_key_file_set_string(config, "VTE", "colour_fore", tmp_string); g_free(tmp_string); tmp_string = utils_get_hex_from_color(&vc->colour_back); g_key_file_set_string(config, "VTE", "colour_back", tmp_string); g_free(tmp_string); } #endif } static void save_ui_prefs(GKeyFile *config) { g_key_file_set_boolean(config, PACKAGE, "sidebar_visible", ui_prefs.sidebar_visible); g_key_file_set_boolean(config, PACKAGE, "statusbar_visible", interface_prefs.statusbar_visible); g_key_file_set_boolean(config, PACKAGE, "msgwindow_visible", ui_prefs.msgwindow_visible); g_key_file_set_boolean(config, PACKAGE, "fullscreen", ui_prefs.fullscreen); g_key_file_set_boolean(config, PACKAGE, "symbols_group_by_type", ui_prefs.symbols_group_by_type); g_key_file_set_string(config, PACKAGE, "color_picker_palette", ui_prefs.color_picker_palette); /* get the text from the scribble textview */ { GtkTextBuffer *buffer; GtkTextIter start, end, iter; GtkTextMark *mark; buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(msgwindow.scribble)); gtk_text_buffer_get_bounds(buffer, &start, &end); scribble_text = gtk_text_buffer_get_text(buffer, &start, &end, FALSE); g_key_file_set_string(config, PACKAGE, "scribble_text", scribble_text); g_free(scribble_text); mark = gtk_text_buffer_get_insert(buffer); gtk_text_buffer_get_iter_at_mark(buffer, &iter, mark); scribble_pos = gtk_text_iter_get_offset(&iter); g_key_file_set_integer(config, PACKAGE, "scribble_pos", scribble_pos); } g_key_file_set_string(config, PACKAGE, "custom_date_format", ui_prefs.custom_date_format); if (ui_prefs.custom_commands != NULL) { g_key_file_set_string_list(config, PACKAGE, "custom_commands", (const gchar**) ui_prefs.custom_commands, g_strv_length(ui_prefs.custom_commands)); g_key_file_set_string_list(config, PACKAGE, "custom_commands_labels", (const gchar**) ui_prefs.custom_commands_labels, g_strv_length(ui_prefs.custom_commands_labels)); } } static void save_ui_session(GKeyFile *config) { if (prefs.save_winpos || prefs.save_wingeom) { GdkWindowState wstate; g_key_file_set_integer(config, PACKAGE, "treeview_position", gtk_paned_get_position(GTK_PANED(ui_lookup_widget(main_widgets.window, "hpaned1")))); g_key_file_set_integer(config, PACKAGE, "msgwindow_position", gtk_paned_get_position(GTK_PANED(ui_lookup_widget(main_widgets.window, "vpaned1")))); gtk_window_get_position(GTK_WINDOW(main_widgets.window), &ui_prefs.geometry[0], &ui_prefs.geometry[1]); gtk_window_get_size(GTK_WINDOW(main_widgets.window), &ui_prefs.geometry[2], &ui_prefs.geometry[3]); wstate = gdk_window_get_state(gtk_widget_get_window(main_widgets.window)); ui_prefs.geometry[4] = (wstate & GDK_WINDOW_STATE_MAXIMIZED) ? 1 : 0; g_key_file_set_integer_list(config, PACKAGE, "geometry", ui_prefs.geometry, 5); } } static void write_config_file(ConfigPayload payload) { GKeyFile *config = g_key_file_new(); const gchar *filename; gchar *configfile; gchar *data; filename = payload == SESSION ? SESSION_FILE : PREFS_FILE; configfile = g_build_filename(app->configdir, filename, NULL); g_key_file_load_from_file(config, configfile, G_KEY_FILE_NONE, NULL); switch (payload) { case PREFS: /* this signal can be used e.g. to prepare any settings before Stash code reads them below */ g_signal_emit_by_name(geany_object, "save-settings", config); save_dialog_prefs(config); save_ui_prefs(config); break; case SESSION: save_recent_files(config, ui_prefs.recent_queue, "recent_files"); save_recent_files(config, ui_prefs.recent_projects_queue, "recent_projects"); project_save_prefs(config); /* save project filename, etc. */ save_ui_session(config); if (cl_options.load_session && app->project == NULL) configuration_save_session_files(config); #ifdef HAVE_VTE else if (vte_info.have_vte) { vte_get_working_directory(); /* refresh vte_info.dir */ g_key_file_set_string(config, "VTE", "last_dir", vte_info.dir); } #endif break; case MAX_PAYLOAD: g_assert_not_reached(); } /* new settings should be added in init_pref_groups() */ settings_action(config, SETTING_WRITE, payload); /* write the file */ data = g_key_file_to_data(config, NULL, NULL); utils_write_file(configfile, data); g_free(data); g_key_file_free(config); g_free(configfile); } void configuration_save(void) { /* save all configuration files * it is probably not very efficient to write both files every time * could be more selective about which file is saved when */ write_config_file(PREFS); write_config_file(SESSION); } static void load_recent_files(GKeyFile *config, GQueue *queue, const gchar *key) { gchar **recent_files; gsize i, len = 0; recent_files = g_key_file_get_string_list(config, "files", key, &len, NULL); if (recent_files != NULL) { for (i = 0; (i < len) && (i < file_prefs.mru_length); i++) { gchar *filename = g_strdup(recent_files[i]); g_queue_push_tail(queue, filename); } g_strfreev(recent_files); } } /* * Load session list from the given keyfile and return an array containg the file names * */ GPtrArray *configuration_load_session_files(GKeyFile *config) { guint i; gboolean have_session_files; gchar entry[16]; gchar **tmp_array; GError *error = NULL; GPtrArray *files; session_notebook_page = utils_get_setting_integer(config, "files", "current_page", -1); files = g_ptr_array_new(); have_session_files = TRUE; i = 0; while (have_session_files) { g_snprintf(entry, sizeof(entry), "FILE_NAME_%d", i); tmp_array = g_key_file_get_string_list(config, "files", entry, NULL, &error); if (! tmp_array || error) { g_error_free(error); error = NULL; have_session_files = FALSE; } g_ptr_array_add(files, tmp_array); i++; } #ifdef HAVE_VTE /* BUG: after loading project at startup, closing project doesn't restore old VTE path */ if (vte_info.have_vte) { gchar *tmp_string = utils_get_setting_string(config, "VTE", "last_dir", NULL); vte_cwd(tmp_string,TRUE); g_free(tmp_string); } #endif return files; } #ifdef HAVE_VTE static void get_setting_color(GKeyFile *config, const gchar *section, const gchar *key, GdkColor *color, const gchar *default_color) { gchar *str = utils_get_setting_string(config, section, key, NULL); if (str == NULL || ! utils_parse_color(str, color)) utils_parse_color(default_color, color); g_free(str); } #endif /* note: new settings should be added in init_pref_groups() */ static void load_dialog_prefs(GKeyFile *config) { gchar *tmp_string, *tmp_string2; const gchar *default_charset = NULL; gchar *cmd; /* compatibility with Geany 0.20 */ if (!g_key_file_has_key(config, PACKAGE, atomic_file_saving_key, NULL)) { g_key_file_set_boolean(config, PACKAGE, atomic_file_saving_key, utils_get_setting_boolean(config, PACKAGE, "use_safe_file_saving", FALSE)); } /* compatibility with Geany 0.21 */ { gboolean suppress_search_dialogs = utils_get_setting_boolean(config, PACKAGE, "pref_main_suppress_search_dialogs", FALSE); if (!g_key_file_has_key(config, "search", "pref_search_always_wrap", NULL)) g_key_file_set_boolean(config, "search", "pref_search_always_wrap", suppress_search_dialogs); if (!g_key_file_has_key(config, "search", "pref_search_hide_find_dialog", NULL)) g_key_file_set_boolean(config, "search", "pref_search_hide_find_dialog", suppress_search_dialogs); } /* general */ prefs.confirm_exit = utils_get_setting_boolean(config, PACKAGE, "pref_main_confirm_exit", FALSE); prefs.suppress_status_messages = utils_get_setting_boolean(config, PACKAGE, "pref_main_suppress_status_messages", FALSE); prefs.load_session = utils_get_setting_boolean(config, PACKAGE, "pref_main_load_session", TRUE); project_prefs.project_file_in_basedir = utils_get_setting_boolean(config, PACKAGE, "pref_main_project_file_in_basedir", TRUE); prefs.save_winpos = utils_get_setting_boolean(config, PACKAGE, "pref_main_save_winpos", TRUE); prefs.save_wingeom = utils_get_setting_boolean(config, PACKAGE, "pref_main_save_wingeom", prefs.save_winpos); prefs.beep_on_errors = utils_get_setting_boolean(config, PACKAGE, "beep_on_errors", TRUE); prefs.switch_to_status = utils_get_setting_boolean(config, PACKAGE, "switch_msgwin_pages", FALSE); prefs.auto_focus = utils_get_setting_boolean(config, PACKAGE, "auto_focus", FALSE); /* interface */ interface_prefs.tab_pos_editor = utils_get_setting_integer(config, PACKAGE, "tab_pos_editor", GTK_POS_TOP); interface_prefs.tab_pos_msgwin = utils_get_setting_integer(config, PACKAGE, "tab_pos_msgwin",GTK_POS_LEFT); interface_prefs.sidebar_symbol_visible = utils_get_setting_boolean(config, PACKAGE, "sidebar_symbol_visible", TRUE); interface_prefs.sidebar_openfiles_visible = utils_get_setting_boolean(config, PACKAGE, "sidebar_openfiles_visible", TRUE); interface_prefs.statusbar_visible = utils_get_setting_boolean(config, PACKAGE, "statusbar_visible", TRUE); file_prefs.tab_order_ltr = utils_get_setting_boolean(config, PACKAGE, "tab_order_ltr", TRUE); file_prefs.tab_order_beside = utils_get_setting_boolean(config, PACKAGE, "tab_order_beside", FALSE); interface_prefs.show_notebook_tabs = utils_get_setting_boolean(config, PACKAGE, "show_notebook_tabs", TRUE); file_prefs.show_tab_cross = utils_get_setting_boolean(config, PACKAGE, "show_tab_cross", TRUE); interface_prefs.editor_font = utils_get_setting_string(config, PACKAGE, "editor_font", GEANY_DEFAULT_FONT_EDITOR); interface_prefs.tagbar_font = utils_get_setting_string(config, PACKAGE, "tagbar_font", GEANY_DEFAULT_FONT_SYMBOL_LIST); interface_prefs.msgwin_font = utils_get_setting_string(config, PACKAGE, "msgwin_font", GEANY_DEFAULT_FONT_MSG_WINDOW); /* display, editor */ editor_prefs.long_line_enabled = utils_get_setting_boolean(config, PACKAGE, "long_line_enabled", TRUE); editor_prefs.long_line_type = utils_get_setting_integer(config, PACKAGE, "long_line_type", 0); if (editor_prefs.long_line_type == 2) /* backward compatibility */ { editor_prefs.long_line_type = 0; editor_prefs.long_line_enabled = FALSE; } editor_prefs.long_line_color = utils_get_setting_string(config, PACKAGE, "long_line_color", "#C2EBC2"); editor_prefs.long_line_column = utils_get_setting_integer(config, PACKAGE, "long_line_column", 72); editor_prefs.symbolcompletion_min_chars = utils_get_setting_integer(config, PACKAGE, "symbolcompletion_min_chars", GEANY_MIN_SYMBOLLIST_CHARS); editor_prefs.symbolcompletion_max_height = utils_get_setting_integer(config, PACKAGE, "symbolcompletion_max_height", GEANY_MAX_SYMBOLLIST_HEIGHT); editor_prefs.line_wrapping = utils_get_setting_boolean(config, PACKAGE, "line_wrapping", FALSE); /* default is off for better performance */ editor_prefs.use_indicators = utils_get_setting_boolean(config, PACKAGE, "use_indicators", TRUE); editor_prefs.show_indent_guide = utils_get_setting_boolean(config, PACKAGE, "show_indent_guide", FALSE); editor_prefs.show_white_space = utils_get_setting_boolean(config, PACKAGE, "show_white_space", FALSE); editor_prefs.show_line_endings = utils_get_setting_boolean(config, PACKAGE, "show_line_endings", FALSE); editor_prefs.show_line_endings_only_when_differ = utils_get_setting_boolean(config, PACKAGE, "show_line_endings_only_when_differ", FALSE); editor_prefs.scroll_stop_at_last_line = utils_get_setting_boolean(config, PACKAGE, "scroll_stop_at_last_line", TRUE); editor_prefs.auto_close_xml_tags = utils_get_setting_boolean(config, PACKAGE, "auto_close_xml_tags", TRUE); editor_prefs.complete_snippets = utils_get_setting_boolean(config, PACKAGE, "complete_snippets", TRUE); editor_prefs.auto_complete_symbols = utils_get_setting_boolean(config, PACKAGE, "auto_complete_symbols", TRUE); editor_prefs.folding = utils_get_setting_boolean(config, PACKAGE, "use_folding", TRUE); editor_prefs.unfold_all_children = utils_get_setting_boolean(config, PACKAGE, "unfold_all_children", FALSE); editor_prefs.show_markers_margin = utils_get_setting_boolean(config, PACKAGE, "show_markers_margin", TRUE); editor_prefs.show_linenumber_margin = utils_get_setting_boolean(config, PACKAGE, "show_linenumber_margin", TRUE); editor_prefs.disable_dnd = utils_get_setting_boolean(config, PACKAGE, "pref_editor_disable_dnd", FALSE); editor_prefs.smart_home_key = utils_get_setting_boolean(config, PACKAGE, "pref_editor_smart_home_key", TRUE); editor_prefs.newline_strip = utils_get_setting_boolean(config, PACKAGE, "pref_editor_newline_strip", FALSE); editor_prefs.line_break_column = utils_get_setting_integer(config, PACKAGE, "line_break_column", 72); editor_prefs.auto_continue_multiline = utils_get_setting_boolean(config, PACKAGE, "auto_continue_multiline", TRUE); editor_prefs.comment_toggle_mark = utils_get_setting_string(config, PACKAGE, "comment_toggle_mark", GEANY_TOGGLE_MARK); editor_prefs.autoclose_chars = utils_get_setting_integer(config, PACKAGE, "autoclose_chars", 0); /* Files * use current locale encoding as default for new files (should be UTF-8 in most cases) */ g_get_charset(&default_charset); tmp_string = utils_get_setting_string(config, PACKAGE, "pref_editor_default_new_encoding", default_charset); if (tmp_string) { const GeanyEncoding *enc = encodings_get_from_charset(tmp_string); if (enc != NULL) file_prefs.default_new_encoding = enc->idx; else file_prefs.default_new_encoding = GEANY_ENCODING_UTF_8; g_free(tmp_string); } tmp_string = utils_get_setting_string(config, PACKAGE, "pref_editor_default_open_encoding", "none"); if (tmp_string) { const GeanyEncoding *enc = NULL; if (strcmp(tmp_string, "none") != 0) enc = encodings_get_from_charset(tmp_string); if (enc != NULL) file_prefs.default_open_encoding = enc->idx; else file_prefs.default_open_encoding = -1; g_free(tmp_string); } file_prefs.default_eol_character = utils_get_setting_integer(config, PACKAGE, "default_eol_character", GEANY_DEFAULT_EOL_CHARACTER); file_prefs.replace_tabs = utils_get_setting_boolean(config, PACKAGE, "pref_editor_replace_tabs", FALSE); file_prefs.ensure_convert_new_lines = utils_get_setting_boolean(config, PACKAGE, "pref_editor_ensure_convert_line_endings", FALSE); file_prefs.final_new_line = utils_get_setting_boolean(config, PACKAGE, "pref_editor_new_line", TRUE); file_prefs.strip_trailing_spaces = utils_get_setting_boolean(config, PACKAGE, "pref_editor_trail_space", FALSE); /* toolbar */ toolbar_prefs.visible = utils_get_setting_boolean(config, PACKAGE, "pref_toolbar_show", TRUE); toolbar_prefs.append_to_menu = utils_get_setting_boolean(config, PACKAGE, "pref_toolbar_append_to_menu", FALSE); { toolbar_prefs.use_gtk_default_style = utils_get_setting_boolean(config, PACKAGE, "pref_toolbar_use_gtk_default_style", TRUE); if (! toolbar_prefs.use_gtk_default_style) toolbar_prefs.icon_style = utils_get_setting_integer(config, PACKAGE, "pref_toolbar_icon_style", GTK_TOOLBAR_ICONS); toolbar_prefs.use_gtk_default_icon = utils_get_setting_boolean(config, PACKAGE, "pref_toolbar_use_gtk_default_icon", TRUE); if (! toolbar_prefs.use_gtk_default_icon) toolbar_prefs.icon_size = utils_get_setting_integer(config, PACKAGE, "pref_toolbar_icon_size", GTK_ICON_SIZE_LARGE_TOOLBAR); } /* VTE */ #ifdef HAVE_VTE vte_info.load_vte = utils_get_setting_boolean(config, "VTE", "load_vte", TRUE); if (vte_info.load_vte && vte_info.load_vte_cmdline /* not disabled on the cmdline */) { VteConfig *vc = &vte_config; struct passwd *pw = getpwuid(getuid()); const gchar *shell = (pw != NULL) ? pw->pw_shell : "/bin/sh"; #ifdef __APPLE__ /* Geany is started using launchd on OS X and we don't get any environment variables * so PS1 isn't defined. Start as a login shell to read the corresponding config files. */ if (strcmp(shell, "/bin/bash") == 0) shell = "/bin/bash -l"; #endif vte_info.dir = utils_get_setting_string(config, "VTE", "last_dir", NULL); if ((vte_info.dir == NULL || utils_str_equal(vte_info.dir, "")) && pw != NULL) /* last dir is not set, fallback to user's home directory */ SETPTR(vte_info.dir, g_strdup(pw->pw_dir)); else if (vte_info.dir == NULL && pw == NULL) /* fallback to root */ vte_info.dir = g_strdup("/"); vc->shell = utils_get_setting_string(config, "VTE", "shell", shell); vc->font = utils_get_setting_string(config, "VTE", "font", GEANY_DEFAULT_FONT_EDITOR); vc->scroll_on_key = utils_get_setting_boolean(config, "VTE", "scroll_on_key", TRUE); vc->scroll_on_out = utils_get_setting_boolean(config, "VTE", "scroll_on_out", TRUE); vc->enable_bash_keys = utils_get_setting_boolean(config, "VTE", "enable_bash_keys", TRUE); vc->ignore_menu_bar_accel = utils_get_setting_boolean(config, "VTE", "ignore_menu_bar_accel", FALSE); vc->follow_path = utils_get_setting_boolean(config, "VTE", "follow_path", FALSE); vc->run_in_vte = utils_get_setting_boolean(config, "VTE", "run_in_vte", FALSE); vc->skip_run_script = utils_get_setting_boolean(config, "VTE", "skip_run_script", FALSE); vc->cursor_blinks = utils_get_setting_boolean(config, "VTE", "cursor_blinks", FALSE); vc->scrollback_lines = utils_get_setting_integer(config, "VTE", "scrollback_lines", 500); get_setting_color(config, "VTE", "colour_fore", &vc->colour_fore, "#ffffff"); get_setting_color(config, "VTE", "colour_back", &vc->colour_back, "#000000"); } #endif /* templates */ template_prefs.developer = utils_get_setting_string(config, PACKAGE, "pref_template_developer", g_get_real_name()); template_prefs.company = utils_get_setting_string(config, PACKAGE, "pref_template_company", ""); tmp_string = utils_get_initials(template_prefs.developer); template_prefs.initials = utils_get_setting_string(config, PACKAGE, "pref_template_initial", tmp_string); g_free(tmp_string); template_prefs.version = utils_get_setting_string(config, PACKAGE, "pref_template_version", "1.0"); tmp_string = g_strdup_printf("%s@%s", g_get_user_name(), g_get_host_name()); template_prefs.mail = utils_get_setting_string(config, PACKAGE, "pref_template_mail", tmp_string); g_free(tmp_string); template_prefs.year_format = utils_get_setting_string(config, PACKAGE, "pref_template_year", GEANY_TEMPLATES_FORMAT_YEAR); template_prefs.date_format = utils_get_setting_string(config, PACKAGE, "pref_template_date", GEANY_TEMPLATES_FORMAT_DATE); template_prefs.datetime_format = utils_get_setting_string(config, PACKAGE, "pref_template_datetime", GEANY_TEMPLATES_FORMAT_DATETIME); /* tools */ cmd = utils_get_setting_string(config, "tools", "terminal_cmd", ""); if (EMPTY(cmd)) { SETPTR(cmd, utils_get_setting_string(config, "tools", "term_cmd", "")); if (!EMPTY(cmd)) { tmp_string = cmd; #ifdef G_OS_WIN32 if (strstr(cmd, "cmd.exe")) cmd = g_strconcat(cmd, " /Q /C %c", NULL); else cmd = g_strconcat(cmd, " %c", NULL); #else cmd = g_strconcat(cmd, " -e \"/bin/sh %c\"", NULL); #endif g_free(tmp_string); } else SETPTR(cmd, g_strdup(GEANY_DEFAULT_TOOLS_TERMINAL)); } tool_prefs.term_cmd = cmd; tool_prefs.browser_cmd = utils_get_setting_string(config, "tools", "browser_cmd", GEANY_DEFAULT_TOOLS_BROWSER); tool_prefs.grep_cmd = utils_get_setting_string(config, "tools", "grep_cmd", GEANY_DEFAULT_TOOLS_GREP); tool_prefs.context_action_cmd = utils_get_setting_string(config, PACKAGE, "context_action_cmd", ""); /* printing */ tmp_string2 = g_find_program_in_path(GEANY_DEFAULT_TOOLS_PRINTCMD); if (!EMPTY(tmp_string2)) { #ifdef G_OS_WIN32 tmp_string = g_strconcat(GEANY_DEFAULT_TOOLS_PRINTCMD, " \"%f\"", NULL); #else tmp_string = g_strconcat(GEANY_DEFAULT_TOOLS_PRINTCMD, " '%f'", NULL); #endif } else { tmp_string = g_strdup(""); } printing_prefs.external_print_cmd = utils_get_setting_string(config, "printing", "print_cmd", tmp_string); g_free(tmp_string); g_free(tmp_string2); printing_prefs.use_gtk_printing = utils_get_setting_boolean(config, "printing", "use_gtk_printing", TRUE); printing_prefs.print_line_numbers = utils_get_setting_boolean(config, "printing", "print_line_numbers", TRUE); printing_prefs.print_page_numbers = utils_get_setting_boolean(config, "printing", "print_page_numbers", TRUE); printing_prefs.print_page_header = utils_get_setting_boolean(config, "printing", "print_page_header", TRUE); printing_prefs.page_header_basename = utils_get_setting_boolean(config, "printing", "page_header_basename", FALSE); printing_prefs.page_header_datefmt = utils_get_setting_string(config, "printing", "page_header_datefmt", "%c"); } static void load_ui_prefs(GKeyFile *config) { ui_prefs.sidebar_visible = utils_get_setting_boolean(config, PACKAGE, "sidebar_visible", TRUE); ui_prefs.msgwindow_visible = utils_get_setting_boolean(config, PACKAGE, "msgwindow_visible", TRUE); ui_prefs.fullscreen = utils_get_setting_boolean(config, PACKAGE, "fullscreen", FALSE); ui_prefs.symbols_group_by_type = utils_get_setting_boolean(config, PACKAGE, "symbols_group_by_type", TRUE); ui_prefs.custom_date_format = utils_get_setting_string(config, PACKAGE, "custom_date_format", ""); ui_prefs.custom_commands = g_key_file_get_string_list(config, PACKAGE, "custom_commands", NULL, NULL); ui_prefs.custom_commands_labels = g_key_file_get_string_list(config, PACKAGE, "custom_commands_labels", NULL, NULL); ui_prefs.color_picker_palette = utils_get_setting_string(config, PACKAGE, "color_picker_palette", ""); /* Load the saved color picker palette */ if (!EMPTY(ui_prefs.color_picker_palette)) { GtkSettings *settings; settings = gtk_settings_get_for_screen(gtk_window_get_screen(GTK_WINDOW(main_widgets.window))); g_object_set(G_OBJECT(settings), "gtk-color-palette", ui_prefs.color_picker_palette, NULL); } /* sanitize custom commands labels */ if (ui_prefs.custom_commands || ui_prefs.custom_commands_labels) { guint i; guint cc_len = ui_prefs.custom_commands ? g_strv_length(ui_prefs.custom_commands) : 0; guint cc_labels_len = ui_prefs.custom_commands_labels ? g_strv_length(ui_prefs.custom_commands_labels) : 0; /* not enough items, resize and fill */ if (cc_labels_len < cc_len) { ui_prefs.custom_commands_labels = g_realloc(ui_prefs.custom_commands_labels, (cc_len + 1) * sizeof *ui_prefs.custom_commands_labels); for (i = cc_labels_len; i < cc_len; i++) ui_prefs.custom_commands_labels[i] = g_strdup(""); ui_prefs.custom_commands_labels[cc_len] = NULL; } /* too many items, cut off */ else if (cc_labels_len > cc_len) { for (i = cc_len; i < cc_labels_len; i++) { g_free(ui_prefs.custom_commands_labels[i]); ui_prefs.custom_commands_labels[i] = NULL; } } } scribble_text = utils_get_setting_string(config, PACKAGE, "scribble_text", _("Type here what you want, use it as a notice/scratch board")); scribble_pos = utils_get_setting_integer(config, PACKAGE, "scribble_pos", -1); } static void load_ui_session(GKeyFile *config) { gint *geo; gsize geo_len; geo = g_key_file_get_integer_list(config, PACKAGE, "geometry", &geo_len, NULL); if (! geo || geo_len < 5) { ui_prefs.geometry[0] = -1; ui_prefs.geometry[1] = -1; ui_prefs.geometry[2] = -1; ui_prefs.geometry[3] = -1; ui_prefs.geometry[4] = 0; } else { /* don't use insane values but when main windows was maximized last time, pos might be * negative (due to differences in root window and window decorations) */ /* quitting when minimized can make pos -32000, -32000 on Windows! */ ui_prefs.geometry[0] = MAX(-1, geo[0]); ui_prefs.geometry[1] = MAX(-1, geo[1]); ui_prefs.geometry[2] = MAX(-1, geo[2]); ui_prefs.geometry[3] = MAX(-1, geo[3]); ui_prefs.geometry[4] = geo[4] != 0; } hpan_position = utils_get_setting_integer(config, PACKAGE, "treeview_position", 156); vpan_position = utils_get_setting_integer(config, PACKAGE, "msgwindow_position", (geo) ? (GEANY_MSGWIN_HEIGHT + geo[3] - 440) : (GEANY_MSGWIN_HEIGHT + GEANY_WINDOW_DEFAULT_HEIGHT - 440)); g_free(geo); } /* * Save current session in default configuration file */ void configuration_save_default_session(void) { gchar *configfile = g_build_filename(app->configdir, SESSION_FILE, NULL); gchar *data; GKeyFile *config = g_key_file_new(); g_key_file_load_from_file(config, configfile, G_KEY_FILE_NONE, NULL); if (cl_options.load_session) configuration_save_session_files(config); /* write the file */ data = g_key_file_to_data(config, NULL, NULL); utils_write_file(configfile, data); g_free(data); g_key_file_free(config); g_free(configfile); } void configuration_clear_default_session(void) { gchar *configfile = g_build_filename(app->configdir, SESSION_FILE, NULL); gchar *data; GKeyFile *config = g_key_file_new(); g_key_file_load_from_file(config, configfile, G_KEY_FILE_NONE, NULL); if (cl_options.load_session) remove_session_files(config); /* write the file */ data = g_key_file_to_data(config, NULL, NULL); utils_write_file(configfile, data); g_free(data); g_key_file_free(config); g_free(configfile); } /* * Only reload the session part of the default configuration */ void configuration_load_default_session(void) { gchar *configfile = get_keyfile_for_payload(SESSION); GKeyFile *config = g_key_file_new(); g_return_if_fail(default_session_files == NULL); g_key_file_load_from_file(config, configfile, G_KEY_FILE_NONE, NULL); g_free(configfile); default_session_files = configuration_load_session_files(config); g_key_file_free(config); } static gboolean read_config_file(ConfigPayload payload) { GKeyFile *config = g_key_file_new(); gchar *configfile; configfile = get_keyfile_for_payload(payload); g_key_file_load_from_file(config, configfile, G_KEY_FILE_NONE, NULL); g_free(configfile); /* read stash prefs */ settings_action(config, SETTING_READ, payload); switch (payload) { case PREFS: load_dialog_prefs(config); load_ui_prefs(config); /* build menu, after stash prefs as it uses some of them */ build_set_group_count(GEANY_GBG_FT, build_menu_prefs.number_ft_menu_items); build_set_group_count(GEANY_GBG_NON_FT, build_menu_prefs.number_non_ft_menu_items); build_set_group_count(GEANY_GBG_EXEC, build_menu_prefs.number_exec_menu_items); build_load_menu(config, GEANY_BCS_PREF, NULL); /* this signal can be used e.g. to delay building UI elements until settings have been read */ g_signal_emit_by_name(geany_object, "load-settings", config); break; case SESSION: project_load_prefs(config); load_ui_session(config); load_recent_files(config, ui_prefs.recent_queue, "recent_files"); load_recent_files(config, ui_prefs.recent_projects_queue, "recent_projects"); break; case MAX_PAYLOAD: g_assert_not_reached(); } g_key_file_free(config); return TRUE; } gboolean configuration_load(void) { gboolean prefs_loaded = read_config_file(PREFS); gboolean sess_loaded = read_config_file(SESSION); return prefs_loaded && sess_loaded; } static gboolean open_session_file(gchar **tmp, guint len) { guint pos; const gchar *ft_name; gchar *locale_filename; gchar *unescaped_filename; const gchar *encoding; gint indent_type; gboolean ro, auto_indent, line_wrapping; /** TODO when we have a global pref for line breaking, use its value */ gboolean line_breaking = FALSE; gboolean ret = FALSE; pos = atoi(tmp[0]); ft_name = tmp[1]; ro = atoi(tmp[2]); if (isdigit(tmp[3][0])) { encoding = encodings_get_charset_from_index(atoi(tmp[3])); } else { encoding = &(tmp[3][1]); } indent_type = atoi(tmp[4]); auto_indent = atoi(tmp[5]); line_wrapping = atoi(tmp[6]); /* try to get the locale equivalent for the filename */ unescaped_filename = g_uri_unescape_string(tmp[7], NULL); locale_filename = utils_get_locale_from_utf8(unescaped_filename); if (len > 8) line_breaking = atoi(tmp[8]); if (g_file_test(locale_filename, G_FILE_TEST_IS_REGULAR)) { GeanyFiletype *ft = filetypes_lookup_by_name(ft_name); GeanyDocument *doc = document_open_file_full( NULL, locale_filename, pos, ro, ft, encoding); if (doc) { gint indent_width = doc->editor->indent_width; if (len > 9) indent_width = atoi(tmp[9]); editor_set_indent(doc->editor, indent_type, indent_width); editor_set_line_wrapping(doc->editor, line_wrapping); doc->editor->line_breaking = line_breaking; doc->editor->auto_indent = auto_indent; ret = TRUE; } } else { geany_debug("Could not find file '%s'.", unescaped_filename); } g_free(locale_filename); g_free(unescaped_filename); return ret; } /* Open session files * Note: notebook page switch handler and adding to recent files list is always disabled * for all files opened within this function */ void configuration_open_files(GPtrArray *session_files) { gboolean failure = FALSE; /* necessary to set it to TRUE for project session support */ main_status.opening_session_files++; for (guint i = 0; i < session_files->len; i++) { gchar **tmp = g_ptr_array_index(session_files, i); guint len; if (tmp != NULL && (len = g_strv_length(tmp)) >= 8) { if (! open_session_file(tmp, len)) failure = TRUE; } g_strfreev(tmp); } g_ptr_array_free(session_files, TRUE); if (failure) ui_set_statusbar(TRUE, _("Failed to load one or more session files.")); else document_show_tab_idle(session_notebook_page >= 0 ? document_get_from_page(session_notebook_page) : document_get_current()); session_notebook_page = -1; main_status.opening_session_files--; } /* Open session files * Note: notebook page switch handler and adding to recent files list is always disabled * for all files opened within this function */ void configuration_open_default_session(void) { g_return_if_fail(default_session_files != NULL); configuration_open_files(default_session_files); default_session_files = NULL; } /* set some settings which are already read from the config file, but need other things, like the * realisation of the main window */ void configuration_apply_settings(void) { if (scribble_text) { /* update the scribble widget, because now it's realized */ GtkTextIter iter; GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(msgwindow.scribble)); gtk_text_buffer_set_text(buffer, scribble_text, -1); gtk_text_buffer_get_iter_at_offset(buffer, &iter, scribble_pos); gtk_text_buffer_place_cursor(buffer, &iter); } g_free(scribble_text); /* set the position of the hpaned and vpaned */ if (prefs.save_winpos) { gtk_paned_set_position(GTK_PANED(ui_lookup_widget(main_widgets.window, "hpaned1")), hpan_position); gtk_paned_set_position(GTK_PANED(ui_lookup_widget(main_widgets.window, "vpaned1")), vpan_position); } /* set fullscreen after initial draw so that returning to normal view is the right size. * fullscreen mode is disabled by default, so act only if it is true */ if (ui_prefs.fullscreen) { gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(ui_lookup_widget(main_widgets.window, "menu_fullscreen1")), TRUE); ui_prefs.fullscreen = TRUE; ui_set_fullscreen(); } msgwin_show_hide_tabs(); } static gboolean save_configuration_cb(gpointer data) { if (app->project != NULL) project_write_config(); else configuration_save_default_session(); return G_SOURCE_REMOVE; } static void document_list_changed_cb(GObject *obj, GeanyDocument *doc, gpointer data) { g_return_if_fail(doc != NULL && doc->is_valid); /* save configuration, especially session file list, but only if we are not just starting * and not about to quit */ if (file_prefs.save_config_on_file_change && main_status.main_window_realized && !main_status.opening_session_files && !main_status.quitting) { g_idle_remove_by_data(save_configuration_cb); g_idle_add(save_configuration_cb, save_configuration_cb); } } void configuration_init(void) { keyfile_groups[PREFS] = g_ptr_array_new_with_free_func((GDestroyNotify) stash_group_free); keyfile_groups[SESSION] = g_ptr_array_new_with_free_func((GDestroyNotify) stash_group_free); pref_groups = g_ptr_array_new(); init_pref_groups(); g_signal_connect(geany_object, "document-open", G_CALLBACK(document_list_changed_cb), NULL); g_signal_connect(geany_object, "document-save", G_CALLBACK(document_list_changed_cb), NULL); g_signal_connect(geany_object, "document-close", G_CALLBACK(document_list_changed_cb), NULL); } void configuration_finalize(void) { g_signal_handlers_disconnect_by_func(geany_object, G_CALLBACK(document_list_changed_cb), NULL); g_ptr_array_free(pref_groups, TRUE); g_ptr_array_free(keyfile_groups[SESSION], TRUE); g_ptr_array_free(keyfile_groups[PREFS], TRUE); } geany-2.0/src/stash.c0000644000175000017500000011400614514252267011466 00000000000000/* * stash.c - this file is part of Geany, a fast and lightweight IDE * * Copyright 2008 The Geany contributors * * This program 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; either version 2 of the License, or * (at your option) any later version. * * This program 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /** * @file stash.h * Lightweight library for reading/writing @c GKeyFile settings and synchronizing widgets with * C variables. * * Note: Stash should only depend on GLib and GTK, but currently has some minor * dependencies on Geany's utils.c. * * @section Terms * 'Setting' is used only for data stored on disk or in memory. * 'Pref' can also include visual widget information. * * @section Memory Usage * Stash will not duplicate strings if they are normally static arrays, such as * keyfile group names and key names, string default values, widget_id names, property names. * * @section String Settings * String settings and other dynamically allocated settings will be initialized to NULL when * added to a StashGroup (so they can safely be reassigned later). * * @section Widget Support * Widgets very commonly used in configuration dialogs will be supported with their own function. * Widgets less commonly used such as @c GtkExpander or widget settings that aren't commonly needed * to be persistent won't be directly supported, to keep the library lightweight. However, you can * use stash_group_add_widget_property() to also save these settings for any read/write widget * property. Macros could be added for common widget properties such as @c GtkExpander:"expanded". * * @section settings-example Settings Example * Here we have some settings for a cup - whether it is made of porcelain, who made it, * how many we have, and how much they cost. (Yes, it's a stupid example). * @include stash-example.c * @note You might want to handle the warning/error conditions differently from above. * * @section prefs-example GUI Prefs Example * For prefs, it's the same as the above example but you tell Stash to add widget prefs instead of * just data settings. * * This example uses lookup strings for widgets as they are more flexible than widget pointers. * Code to load and save the settings is omitted - see the first example instead. * * Here we show a dialog with a toggle button for whether the cup should have a handle. * @include stash-gui-example.c * @note This example should also work for other widget containers besides dialogs, e.g. popup menus. */ /* Implementation Note * We dynamically allocate prefs. It would be more efficient for user code to declare * a static array of StashPref structs, but we don't do this because: * * * It would be more ugly (lots of casts and NULLs). * * Less type checking. * * The API & ABI would have to break when adding/changing fields. * * Usually the prefs code isn't what user code will spend most of its time doing, so this * should be efficient enough. */ #include "stash.h" #include "support.h" /* only for _("text") */ #include "utils.h" /* only for foreach_*, utils_get_setting_*(). Stash should not depend on Geany. */ #include /* only for atoi() */ /* GTK3 removed ComboBoxEntry, but we need a value to differentiate combo box with and * without entries, and it must not collide with other GTypes */ #define TYPE_COMBO_BOX_ENTRY get_combo_box_entry_type() static GType get_combo_box_entry_type(void) { static gsize type = 0; if (g_once_init_enter(&type)) { GType g_type = g_type_register_static_simple(GTK_TYPE_COMBO_BOX, "dummy-combo-box-entry", sizeof(GtkComboBoxClass), NULL, sizeof(GtkComboBox), NULL, G_TYPE_FLAG_ABSTRACT); g_once_init_leave(&type, g_type); } return type; } /* storage for StashPref default values */ union Value { gboolean bool_val; gint int_val; gdouble double_val; gchar *str_val; gchar **strv_val; gpointer *ptr_val; GtkWidget *widget_val; }; struct StashPref { GType setting_type; /* e.g. G_TYPE_INT */ gpointer setting; /* Address of a variable */ const gchar *key_name; union Value default_value; /* Default value, as per setting_type above, e.g. .int_val */ GType widget_type; /* e.g. GTK_TYPE_TOGGLE_BUTTON */ StashWidgetID widget_id; /* (GtkWidget*) or (gchar*) */ union { struct EnumWidget *radio_buttons; const gchar *property_name; } extra; /* extra fields depending on widget_type */ }; typedef struct StashPref StashPref; struct StashGroup { guint refcount; /* ref count for GBoxed implementation */ const gchar *name; /* group name to use in the keyfile */ GPtrArray *entries; /* array of (StashPref*) */ gboolean various; /* mark group for display/edit in stash treeview */ const gchar *prefix; /* text to display for Various UI instead of name */ gboolean use_defaults; /* use default values if there's no keyfile entry */ }; typedef struct EnumWidget { StashWidgetID widget_id; gint enum_id; } EnumWidget; typedef enum SettingAction { SETTING_READ, SETTING_WRITE } SettingAction; typedef enum PrefAction { PREF_DISPLAY, PREF_UPDATE } PrefAction; static void handle_boolean_setting(StashGroup *group, StashPref *se, GKeyFile *config, SettingAction action) { gboolean *setting = se->setting; switch (action) { case SETTING_READ: *setting = utils_get_setting_boolean(config, group->name, se->key_name, se->default_value.bool_val); break; case SETTING_WRITE: g_key_file_set_boolean(config, group->name, se->key_name, *setting); break; } } static void handle_double_setting(StashGroup *group, StashPref *se, GKeyFile *config, SettingAction action) { gdouble *setting = se->setting; switch (action) { case SETTING_READ: *setting = utils_get_setting_double(config, group->name, se->key_name, se->default_value.double_val); break; case SETTING_WRITE: g_key_file_set_double(config, group->name, se->key_name, *setting); break; } } static void handle_integer_setting(StashGroup *group, StashPref *se, GKeyFile *config, SettingAction action) { gint *setting = se->setting; switch (action) { case SETTING_READ: *setting = utils_get_setting_integer(config, group->name, se->key_name, se->default_value.int_val); break; case SETTING_WRITE: g_key_file_set_integer(config, group->name, se->key_name, *setting); break; } } static void handle_string_setting(StashGroup *group, StashPref *se, GKeyFile *config, SettingAction action) { gchararray *setting = se->setting; switch (action) { case SETTING_READ: g_free(*setting); *setting = utils_get_setting_string(config, group->name, se->key_name, se->default_value.str_val); break; case SETTING_WRITE: g_key_file_set_string(config, group->name, se->key_name, *setting ? *setting : ""); break; } } static void handle_strv_setting(StashGroup *group, StashPref *se, GKeyFile *config, SettingAction action) { gchararray **setting = se->setting; switch (action) { case SETTING_READ: g_strfreev(*setting); *setting = g_key_file_get_string_list(config, group->name, se->key_name, NULL, NULL); if (*setting == NULL) *setting = g_strdupv(se->default_value.strv_val); break; case SETTING_WRITE: { /* don't try to save a NULL string vector */ const gchar *dummy[] = { "", NULL }; const gchar **strv = *setting ? (const gchar **)*setting : dummy; g_key_file_set_string_list(config, group->name, se->key_name, strv, g_strv_length((gchar **)strv)); break; } } } static void keyfile_action(SettingAction action, StashGroup *group, GKeyFile *keyfile) { StashPref *entry; guint i; foreach_ptr_array(entry, i, group->entries) { /* don't override settings with default values */ if (!group->use_defaults && action == SETTING_READ && !g_key_file_has_key(keyfile, group->name, entry->key_name, NULL)) continue; switch (entry->setting_type) { case G_TYPE_BOOLEAN: handle_boolean_setting(group, entry, keyfile, action); break; case G_TYPE_INT: handle_integer_setting(group, entry, keyfile, action); break; case G_TYPE_DOUBLE: handle_double_setting(group, entry, keyfile, action); break; case G_TYPE_STRING: handle_string_setting(group, entry, keyfile, action); break; default: /* Note: G_TYPE_STRV is not a constant, can't use case label */ if (entry->setting_type == G_TYPE_STRV) handle_strv_setting(group, entry, keyfile, action); else g_warning("Unhandled type for %s::%s in %s()!", group->name, entry->key_name, G_STRFUNC); } } } /** Reads key values from @a keyfile into the group settings. * @note You should still call this even if the keyfile couldn't be loaded from disk * so that all Stash settings are initialized to defaults. * @param group . * @param keyfile Usually loaded from a configuration file first. */ GEANY_API_SYMBOL void stash_group_load_from_key_file(StashGroup *group, GKeyFile *keyfile) { keyfile_action(SETTING_READ, group, keyfile); } /** Writes group settings into key values in @a keyfile. * @a keyfile is usually written to a configuration file afterwards. * @param group . * @param keyfile . */ GEANY_API_SYMBOL void stash_group_save_to_key_file(StashGroup *group, GKeyFile *keyfile) { keyfile_action(SETTING_WRITE, group, keyfile); } /** Reads group settings from a configuration file using @c GKeyFile. * @note Stash settings will be initialized to defaults if the keyfile * couldn't be loaded from disk. * @param group . * @param filename Filename of the file to read, in locale encoding. * @return @c TRUE if a key file could be loaded. * @see stash_group_load_from_key_file(). **/ GEANY_API_SYMBOL gboolean stash_group_load_from_file(StashGroup *group, const gchar *filename) { GKeyFile *keyfile; gboolean ret; keyfile = g_key_file_new(); ret = g_key_file_load_from_file(keyfile, filename, 0, NULL); /* even on failure we load settings to apply defaults */ stash_group_load_from_key_file(group, keyfile); g_key_file_free(keyfile); return ret; } /** Writes group settings to a configuration file using @c GKeyFile. * * @param group . * @param filename Filename of the file to write, in locale encoding. * @param flags Keyfile options - @c G_KEY_FILE_NONE is the most efficient. * @return 0 if the file was successfully written, otherwise the @c errno of the * failed operation is returned. * @see stash_group_save_to_key_file(). **/ GEANY_API_SYMBOL gint stash_group_save_to_file(StashGroup *group, const gchar *filename, GKeyFileFlags flags) { GKeyFile *keyfile; gchar *data; gint ret; keyfile = g_key_file_new(); /* if we need to keep comments or translations, try to load first */ if (flags) g_key_file_load_from_file(keyfile, filename, flags, NULL); stash_group_save_to_key_file(group, keyfile); data = g_key_file_to_data(keyfile, NULL, NULL); ret = utils_write_file(filename, data); g_free(data); g_key_file_free(keyfile); return ret; } static void free_stash_pref(StashPref *pref) { if (pref->widget_type == GTK_TYPE_RADIO_BUTTON) g_free(pref->extra.radio_buttons); g_slice_free(StashPref, pref); } /** Creates a new group. * @param name Name used for @c GKeyFile group. * @return Group. */ GEANY_API_SYMBOL StashGroup *stash_group_new(const gchar *name) { StashGroup *group = g_slice_new0(StashGroup); group->name = name; group->entries = g_ptr_array_new_with_free_func((GDestroyNotify) free_stash_pref); group->use_defaults = TRUE; group->refcount = 1; return group; } /** Frees the memory allocated for setting values in a group. * Useful e.g. to avoid freeing strings individually. * @note This is *not* called by stash_group_free(). * @param group . */ GEANY_API_SYMBOL void stash_group_free_settings(StashGroup *group) { StashPref *entry; guint i; foreach_ptr_array(entry, i, group->entries) { if (entry->setting_type == G_TYPE_STRING) g_free(*(gchararray *) entry->setting); else if (entry->setting_type == G_TYPE_STRV) g_strfreev(*(gchararray **) entry->setting); else continue; *(gpointer**) entry->setting = NULL; } } static StashGroup *stash_group_dup(StashGroup *src) { g_atomic_int_inc(&src->refcount); return src; } /** Frees a group. * @param group . */ GEANY_API_SYMBOL void stash_group_free(StashGroup *group) { if (g_atomic_int_dec_and_test(&group->refcount)) { g_ptr_array_free(group->entries, TRUE); g_slice_free(StashGroup, group); } } /** Gets the GBoxed-derived GType for StashGroup * * @return StashGroup type . */ GEANY_API_SYMBOL GType stash_group_get_type(void); G_DEFINE_BOXED_TYPE(StashGroup, stash_group, stash_group_dup, stash_group_free); /* Used for selecting groups passed to stash_tree_setup(). * @param various @c FALSE by default. * @param prefix @nullable Group prefix or @c NULL to use @c group->name. */ void stash_group_set_various(StashGroup *group, gboolean various, const gchar *prefix) { group->various = various; group->prefix = prefix; } /* When @c FALSE, Stash doesn't change the setting if there is no keyfile entry, so it * remains whatever it was initialized/set to by user code. * @c TRUE by default. */ void stash_group_set_use_defaults(StashGroup *group, gboolean use_defaults) { group->use_defaults = use_defaults; } static StashPref * add_pref(StashGroup *group, GType type, gpointer setting, const gchar *key_name, union Value default_value) { StashPref *entry = g_slice_new(StashPref); *entry = (StashPref) {type, setting, key_name, default_value, G_TYPE_NONE, NULL, {NULL}}; /* init any pointer settings to NULL so they can be freed later */ if (type == G_TYPE_STRING || type == G_TYPE_STRV) { if (group->use_defaults) *(gpointer**)setting = NULL; } g_ptr_array_add(group->entries, entry); return entry; } /** Adds boolean setting. * @param group . * @param setting Address of setting variable. * @param key_name Name for key in a @c GKeyFile. * @param default_value Value to use if the key doesn't exist when loading. */ GEANY_API_SYMBOL void stash_group_add_boolean(StashGroup *group, gboolean *setting, const gchar *key_name, gboolean default_value) { add_pref(group, G_TYPE_BOOLEAN, setting, key_name, (union Value) {.bool_val = default_value}); } /** Adds double setting. * @param group . * @param setting Address of setting variable. * @param key_name Name for key in a @c GKeyFile. * @param default_value Value to use if the key doesn't exist when loading. */ GEANY_API_SYMBOL void stash_group_add_double(StashGroup *group, gdouble *setting, const gchar *key_name, gdouble default_value) { add_pref(group, G_TYPE_DOUBLE, setting, key_name, (union Value) {.double_val = default_value}); } /** Adds integer setting. * @param group . * @param setting Address of setting variable. * @param key_name Name for key in a @c GKeyFile. * @param default_value Value to use if the key doesn't exist when loading. */ GEANY_API_SYMBOL void stash_group_add_integer(StashGroup *group, gint *setting, const gchar *key_name, gint default_value) { add_pref(group, G_TYPE_INT, setting, key_name, (union Value) {.int_val = default_value}); } /** Adds string setting. * The contents of @a setting will be initialized to @c NULL. * @param group . * @param setting Address of setting variable. * @param key_name Name for key in a @c GKeyFile. * @param default_value @nullable String to copy if the key doesn't exist when loading, or @c NULL. */ GEANY_API_SYMBOL void stash_group_add_string(StashGroup *group, gchar **setting, const gchar *key_name, const gchar *default_value) { add_pref(group, G_TYPE_STRING, setting, key_name, (union Value) {.str_val = (gchar *) default_value}); } /** Adds string vector setting (array of strings). * The contents of @a setting will be initialized to @c NULL. * @param group . * @param setting Address of setting variable. * @param key_name Name for key in a @c GKeyFile. * @param default_value Vector to copy if the key doesn't exist when loading. Usually @c NULL. */ GEANY_API_SYMBOL void stash_group_add_string_vector(StashGroup *group, gchar ***setting, const gchar *key_name, const gchar **default_value) { add_pref(group, G_TYPE_STRV, setting, key_name, (union Value) {.strv_val = (gchar **) default_value}); } /* *** GTK-related functions *** */ static void handle_toggle_button(GtkWidget *widget, gboolean *setting, PrefAction action) { switch (action) { case PREF_DISPLAY: gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), *setting); break; case PREF_UPDATE: *setting = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); break; } } static void handle_spin_button(GtkWidget *widget, StashPref *entry, PrefAction action) { gint *setting = entry->setting; g_assert(entry->setting_type == G_TYPE_INT); /* only int spin prefs */ switch (action) { case PREF_DISPLAY: gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget), *setting); break; case PREF_UPDATE: /* if the widget is focussed, the value might not be updated */ gtk_spin_button_update(GTK_SPIN_BUTTON(widget)); *setting = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget)); break; } } static void handle_combo_box(GtkWidget *widget, StashPref *entry, PrefAction action) { gint *setting = entry->setting; switch (action) { case PREF_DISPLAY: gtk_combo_box_set_active(GTK_COMBO_BOX(widget), *setting); break; case PREF_UPDATE: *setting = gtk_combo_box_get_active(GTK_COMBO_BOX(widget)); break; } } static void handle_entry(GtkWidget *widget, StashPref *entry, PrefAction action) { gchararray *setting = entry->setting; switch (action) { case PREF_DISPLAY: gtk_entry_set_text(GTK_ENTRY(widget), *setting); break; case PREF_UPDATE: g_free(*setting); *setting = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget))); break; } } static void handle_combo_box_entry(GtkWidget *widget, StashPref *entry, PrefAction action) { widget = gtk_bin_get_child(GTK_BIN(widget)); handle_entry(widget, entry, action); } /* taken from Glade 2.x generated support.c */ static GtkWidget* lookup_widget(GtkWidget *widget, const gchar *widget_name) { GtkWidget *parent, *found_widget; g_return_val_if_fail(widget != NULL, NULL); g_return_val_if_fail(widget_name != NULL, NULL); for (;;) { if (GTK_IS_MENU(widget)) parent = gtk_menu_get_attach_widget(GTK_MENU(widget)); else parent = gtk_widget_get_parent(widget); if (parent == NULL) parent = (GtkWidget*) g_object_get_data(G_OBJECT(widget), "GladeParentKey"); if (parent == NULL) break; widget = parent; } found_widget = (GtkWidget*) g_object_get_data(G_OBJECT(widget), widget_name); if (G_UNLIKELY(found_widget == NULL)) g_warning("Widget not found: %s", widget_name); return found_widget; } static GtkWidget * get_widget(GtkWidget *owner, StashWidgetID widget_id) { GtkWidget *widget; if (owner) widget = lookup_widget(owner, (const gchar *)widget_id); else widget = (GtkWidget *)widget_id; if (!GTK_IS_WIDGET(widget)) { g_warning("Unknown widget in %s()!", G_STRFUNC); return NULL; } return widget; } static void handle_radio_button(GtkWidget *widget, gint enum_id, gboolean *setting, PrefAction action) { switch (action) { case PREF_DISPLAY: if (*setting == enum_id) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), TRUE); break; case PREF_UPDATE: if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) *setting = enum_id; break; } } static void handle_radio_buttons(GtkWidget *owner, StashPref *entry, PrefAction action) { EnumWidget *field = entry->extra.radio_buttons; gsize count = 0; GtkWidget *widget = NULL; while (1) { widget = get_widget(owner, field->widget_id); if (!widget) continue; count++; handle_radio_button(widget, field->enum_id, entry->setting, action); field++; if (!field->widget_id) break; } if (g_slist_length(gtk_radio_button_get_group(GTK_RADIO_BUTTON(widget))) != count) g_warning("Missing/invalid radio button widget IDs found!"); } static void handle_widget_property(GtkWidget *widget, StashPref *entry, PrefAction action) { GObject *object = G_OBJECT(widget); const gchar *name = entry->extra.property_name; switch (action) { case PREF_DISPLAY: if (entry->setting_type == G_TYPE_BOOLEAN) g_object_set(object, name, *(gboolean*)entry->setting, NULL); else if (entry->setting_type == G_TYPE_INT) g_object_set(object, name, *(gint*)entry->setting, NULL); else if (entry->setting_type == G_TYPE_STRING) g_object_set(object, name, *(gchararray*)entry->setting, NULL); else if (entry->setting_type == G_TYPE_STRV) g_object_set(object, name, *(gchararray**)entry->setting, NULL); else { g_warning("Unhandled type %s for %s in %s()!", g_type_name(entry->setting_type), entry->key_name, G_STRFUNC); } break; case PREF_UPDATE: if (entry->setting_type == G_TYPE_STRING) g_free(*(gchararray*)entry->setting); else if (entry->setting_type == G_TYPE_STRV) g_strfreev(*(gchararray**)entry->setting); g_object_get(object, name, entry->setting, NULL); break; } } static void pref_action(PrefAction action, StashGroup *group, GtkWidget *owner) { StashPref *entry; guint i; foreach_ptr_array(entry, i, group->entries) { GtkWidget *widget; /* ignore settings with no widgets */ if (entry->widget_type == G_TYPE_NONE) continue; /* radio buttons have several widgets */ if (entry->widget_type == GTK_TYPE_RADIO_BUTTON) { handle_radio_buttons(owner, entry, action); continue; } widget = get_widget(owner, entry->widget_id); if (!widget) { g_warning("Unknown widget for %s::%s in %s()!", group->name, entry->key_name, G_STRFUNC); continue; } /* note: can't use switch for GTK_TYPE macros */ if (entry->widget_type == GTK_TYPE_TOGGLE_BUTTON) handle_toggle_button(widget, entry->setting, action); else if (entry->widget_type == GTK_TYPE_SPIN_BUTTON) handle_spin_button(widget, entry, action); else if (entry->widget_type == GTK_TYPE_COMBO_BOX) handle_combo_box(widget, entry, action); else if (entry->widget_type == TYPE_COMBO_BOX_ENTRY) handle_combo_box_entry(widget, entry, action); else if (entry->widget_type == GTK_TYPE_ENTRY) handle_entry(widget, entry, action); else if (entry->widget_type == G_TYPE_PARAM) handle_widget_property(widget, entry, action); else g_warning("Unhandled type for %s::%s in %s()!", group->name, entry->key_name, G_STRFUNC); } } /** Applies Stash settings to widgets, usually called before displaying the widgets. * The @a owner argument depends on which type you use for @ref StashWidgetID. * @param group . * @param owner If non-NULL, used to lookup widgets by name, otherwise * widget pointers are assumed. * @see stash_group_update(). */ GEANY_API_SYMBOL void stash_group_display(StashGroup *group, GtkWidget *owner) { pref_action(PREF_DISPLAY, group, owner); } /** Applies widget values to Stash settings, usually called after displaying the widgets. * The @a owner argument depends on which type you use for @ref StashWidgetID. * @param group . * @param owner If non-NULL, used to lookup widgets by name, otherwise * widget pointers are assumed. * @see stash_group_display(). */ GEANY_API_SYMBOL void stash_group_update(StashGroup *group, GtkWidget *owner) { pref_action(PREF_UPDATE, group, owner); } static StashPref * add_widget_pref(StashGroup *group, GType setting_type, gpointer setting, const gchar *key_name, union Value default_value, GType widget_type, StashWidgetID widget_id) { StashPref *entry = add_pref(group, setting_type, setting, key_name, default_value); entry->widget_type = widget_type; entry->widget_id = widget_id; return entry; } /** Adds a @c GtkToggleButton (or @c GtkCheckButton) widget pref. * @param group . * @param setting Address of setting variable. * @param key_name Name for key in a @c GKeyFile. * @param default_value Value to use if the key doesn't exist when loading. * @param widget_id @c GtkWidget pointer or string to lookup widget later. * @see stash_group_add_radio_buttons(). */ GEANY_API_SYMBOL void stash_group_add_toggle_button(StashGroup *group, gboolean *setting, const gchar *key_name, gboolean default_value, StashWidgetID widget_id) { add_widget_pref(group, G_TYPE_BOOLEAN, setting, key_name, (union Value) {.bool_val = default_value}, GTK_TYPE_TOGGLE_BUTTON, widget_id); } /** Adds a @c GtkRadioButton widget group pref. * @param group . * @param setting Address of setting variable. * @param key_name Name for key in a @c GKeyFile. * @param default_value Value to use if the key doesn't exist when loading. * @param widget_id @c GtkWidget pointer or string to lookup widget later. * @param enum_id Enum value for @a widget_id. * @param ... pairs of @a widget_id, @a enum_id. * Example (using widget lookup strings, but widget pointers can also work): * @code * enum {FOO, BAR}; * stash_group_add_radio_buttons(group, &which_one_setting, "which_one", BAR, * "radio_foo", FOO, "radio_bar", BAR, NULL); * @endcode */ GEANY_API_SYMBOL void stash_group_add_radio_buttons(StashGroup *group, gint *setting, const gchar *key_name, gint default_value, StashWidgetID widget_id, gint enum_id, ...) { StashPref *entry = add_widget_pref(group, G_TYPE_INT, setting, key_name, (union Value) {.int_val = default_value}, GTK_TYPE_RADIO_BUTTON, NULL); va_list args; gsize count = 1; EnumWidget *item, *array; /* count pairs of args */ va_start(args, enum_id); while (1) { if (!va_arg(args, gpointer)) break; va_arg(args, gint); count++; } va_end(args); array = g_new0(EnumWidget, count + 1); entry->extra.radio_buttons = array; va_start(args, enum_id); foreach_c_array(item, array, count) { if (item == array) { /* first element */ item->widget_id = widget_id; item->enum_id = enum_id; } else { item->widget_id = va_arg(args, gpointer); item->enum_id = va_arg(args, gint); } } va_end(args); } /** Adds a @c GtkSpinButton widget pref. * @param group . * @param setting Address of setting variable. * @param key_name Name for key in a @c GKeyFile. * @param default_value Value to use if the key doesn't exist when loading. * @param widget_id @c GtkWidget pointer or string to lookup widget later. */ GEANY_API_SYMBOL void stash_group_add_spin_button_integer(StashGroup *group, gint *setting, const gchar *key_name, gint default_value, StashWidgetID widget_id) { add_widget_pref(group, G_TYPE_INT, setting, key_name, (union Value) {.int_val = default_value}, GTK_TYPE_SPIN_BUTTON, widget_id); } /** Adds a @c GtkComboBox widget pref. * @param group . * @param setting Address of setting variable. * @param key_name Name for key in a @c GKeyFile. * @param default_value Value to use if the key doesn't exist when loading. * @param widget_id @c GtkWidget pointer or string to lookup widget later. * @see stash_group_add_combo_box_entry(). */ GEANY_API_SYMBOL void stash_group_add_combo_box(StashGroup *group, gint *setting, const gchar *key_name, gint default_value, StashWidgetID widget_id) { add_widget_pref(group, G_TYPE_INT, setting, key_name, (union Value) {.int_val = default_value}, GTK_TYPE_COMBO_BOX, widget_id); } /** Adds a @c GtkComboBoxEntry widget pref. * @param group . * @param setting Address of setting variable. * @param key_name Name for key in a @c GKeyFile. * @param default_value Value to use if the key doesn't exist when loading. * @param widget_id @c GtkWidget pointer or string to lookup widget later. */ /* We could maybe also have something like stash_group_add_combo_box_entry_with_menu() * for the history list - or should that be stored as a separate setting? */ GEANY_API_SYMBOL void stash_group_add_combo_box_entry(StashGroup *group, gchar **setting, const gchar *key_name, const gchar *default_value, StashWidgetID widget_id) { add_widget_pref(group, G_TYPE_STRING, setting, key_name, (union Value) {.str_val = (gchar *) default_value}, TYPE_COMBO_BOX_ENTRY, widget_id); } /** Adds a @c GtkEntry widget pref. * @param group . * @param setting Address of setting variable. * @param key_name Name for key in a @c GKeyFile. * @param default_value Value to use if the key doesn't exist when loading. * @param widget_id @c GtkWidget pointer or string to lookup widget later. */ GEANY_API_SYMBOL void stash_group_add_entry(StashGroup *group, gchar **setting, const gchar *key_name, const gchar *default_value, StashWidgetID widget_id) { add_widget_pref(group, G_TYPE_STRING, setting, key_name, (union Value) {.str_val = (gchar *) default_value}, GTK_TYPE_ENTRY, widget_id); } static GType object_get_property_type(GObject *object, const gchar *property_name) { GObjectClass *klass = G_OBJECT_GET_CLASS(object); GParamSpec *ps; ps = g_object_class_find_property(klass, property_name); return ps->value_type; } /** Adds a widget's read/write property to the stash group. * The property will be set when calling * stash_group_display(), and read when calling stash_group_update(). * @param group . * @param setting Address of e.g. an integer if using an integer property. * @param key_name Name for key in a @c GKeyFile. * @param default_value Value to use if the key doesn't exist when loading. * Should be cast into a pointer e.g. with @c GINT_TO_POINTER(). * @param widget_id @c GtkWidget pointer or string to lookup widget later. * @param property_name . * @param type can be @c 0 if passing a @c GtkWidget as the @a widget_id argument to look it up from the * @c GObject data. * @warning Currently only string GValue properties will be freed before setting; patch for * other types - see @c handle_widget_property(). */ GEANY_API_SYMBOL void stash_group_add_widget_property(StashGroup *group, gpointer setting, const gchar *key_name, gpointer default_value, StashWidgetID widget_id, const gchar *property_name, GType type) { StashPref *entry; if (!type) type = object_get_property_type(G_OBJECT(widget_id), property_name); entry = add_widget_pref(group, type, setting, key_name, (union Value) {.ptr_val = default_value}, G_TYPE_PARAM, widget_id); entry->extra.property_name = property_name; } enum { STASH_TREE_NAME, STASH_TREE_VALUE, STASH_TREE_COUNT }; struct StashTreeValue { const gchar *group_name; StashPref *pref; struct { gchararray tree_string; gint tree_int; } data; }; typedef struct StashTreeValue StashTreeValue; static void stash_tree_renderer_set_data(GtkCellLayout *cell_layout, GtkCellRenderer *cell, GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data) { GType cell_type = GPOINTER_TO_SIZE(user_data); StashTreeValue *value; StashPref *pref; gboolean matches_type; gtk_tree_model_get(model, iter, STASH_TREE_VALUE, &value, -1); pref = value->pref; matches_type = pref->setting_type == cell_type; g_object_set(cell, "visible", matches_type, "sensitive", matches_type, cell_type == G_TYPE_BOOLEAN ? "activatable" : "editable", matches_type, NULL); if (matches_type) { switch (pref->setting_type) { case G_TYPE_BOOLEAN: g_object_set(cell, "active", value->data.tree_int, NULL); break; case G_TYPE_INT: { gchar *text = g_strdup_printf("%d", value->data.tree_int); g_object_set(cell, "text", text, NULL); g_free(text); break; } case G_TYPE_STRING: g_object_set(cell, "text", value->data.tree_string, NULL); break; } } } static void stash_tree_renderer_edited(gchar *path_str, gchar *new_text, GtkTreeModel *model) { GtkTreePath *path; GtkTreeIter iter; StashTreeValue *value; StashPref *pref; path = gtk_tree_path_new_from_string(path_str); gtk_tree_model_get_iter(model, &iter, path); gtk_tree_model_get(model, &iter, STASH_TREE_VALUE, &value, -1); pref = value->pref; switch (pref->setting_type) { case G_TYPE_BOOLEAN: value->data.tree_int = !value->data.tree_int; break; case G_TYPE_INT: value->data.tree_int = atoi(new_text); break; case G_TYPE_STRING: SETPTR(value->data.tree_string, g_strdup(new_text)); break; } gtk_tree_model_row_changed(model, path, &iter); gtk_tree_path_free(path); } static void stash_tree_boolean_toggled(GtkCellRendererToggle *cell, gchar *path_str, GtkTreeModel *model) { stash_tree_renderer_edited(path_str, NULL, model); } static void stash_tree_string_edited(GtkCellRenderer *cell, gchar *path_str, gchar *new_text, GtkTreeModel *model) { stash_tree_renderer_edited(path_str, new_text, model); } static gboolean stash_tree_discard_value(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer user_data) { StashTreeValue *value; gtk_tree_model_get(model, iter, STASH_TREE_VALUE, &value, -1); /* don't access value->pref as it might already have been freed */ g_free(value->data.tree_string); g_free(value); return FALSE; } static void stash_tree_destroy_cb(GtkWidget *widget, gpointer user_data) { GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(widget)); gtk_tree_model_foreach(model, stash_tree_discard_value, NULL); } static void stash_tree_append_pref(StashGroup *group, StashPref *entry, GtkListStore *store, PrefAction action) { GtkTreeIter iter; StashTreeValue *value; gchar *text = NULL; value = g_new0(StashTreeValue, 1); value->group_name = group->name; value->pref = entry; gtk_list_store_append(store, &iter); text = g_strconcat(group->prefix ? group->prefix : group->name, ".", entry->key_name, NULL); gtk_list_store_set(store, &iter, STASH_TREE_NAME, text, STASH_TREE_VALUE, value, -1); g_free(text); } static void stash_tree_append_prefs(GPtrArray *group_array, GtkListStore *store, PrefAction action) { StashGroup *group; guint i, j; StashPref *entry; foreach_ptr_array(group, i, group_array) { if (group->various) { foreach_ptr_array(entry, j, group->entries) stash_tree_append_pref(group, entry, store, action); } } } /* Setups a simple editor for stash preferences based on the widget arguments. * group_array - Array of groups which's settings will be edited. * tree - GtkTreeView in which to edit the preferences. Must be empty. */ void stash_tree_setup(GPtrArray *group_array, GtkTreeView *tree) { GtkListStore *store; GtkTreeModel *model; GtkCellRenderer *cell; GtkTreeViewColumn *column; GtkAdjustment *adjustment; store = gtk_list_store_new(STASH_TREE_COUNT, G_TYPE_STRING, G_TYPE_POINTER); stash_tree_append_prefs(group_array, store, PREF_DISPLAY); gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(store), STASH_TREE_NAME, GTK_SORT_ASCENDING); model = GTK_TREE_MODEL(store); gtk_tree_view_set_model(tree, model); g_object_unref(G_OBJECT(store)); g_signal_connect(tree, "destroy", G_CALLBACK(stash_tree_destroy_cb), NULL); cell = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes(_("Name"), cell, "text", STASH_TREE_NAME, NULL); gtk_tree_view_column_set_sort_column_id(column, STASH_TREE_NAME); gtk_tree_view_column_set_sort_indicator(column, TRUE); gtk_tree_view_append_column(tree, column); column = gtk_tree_view_column_new(); gtk_tree_view_column_set_title(column, _("Value")); gtk_tree_view_append_column(tree, column); /* boolean renderer */ cell = gtk_cell_renderer_toggle_new(); g_signal_connect(cell, "toggled", G_CALLBACK(stash_tree_boolean_toggled), model); gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(column), cell, FALSE); gtk_cell_layout_set_cell_data_func(GTK_CELL_LAYOUT(column), cell, stash_tree_renderer_set_data, GSIZE_TO_POINTER(G_TYPE_BOOLEAN), NULL); /* string renderer */ cell = gtk_cell_renderer_text_new(); g_object_set(cell, "ellipsize", PANGO_ELLIPSIZE_END, NULL); g_signal_connect(cell, "edited", G_CALLBACK(stash_tree_string_edited), model); gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(column), cell, TRUE); gtk_cell_layout_set_cell_data_func(GTK_CELL_LAYOUT(column), cell, stash_tree_renderer_set_data, GSIZE_TO_POINTER(G_TYPE_STRING), NULL); /* integer renderer */ cell = gtk_cell_renderer_spin_new(); adjustment = GTK_ADJUSTMENT(gtk_adjustment_new(0, G_MININT, G_MAXINT, 1, 10, 0)); g_object_set(cell, "adjustment", adjustment, NULL); g_signal_connect(cell, "edited", G_CALLBACK(stash_tree_string_edited), model); gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(column), cell, FALSE); gtk_cell_layout_set_cell_data_func(GTK_CELL_LAYOUT(column), cell, stash_tree_renderer_set_data, GSIZE_TO_POINTER(G_TYPE_INT), NULL); } static void stash_tree_display_pref(StashTreeValue *value, StashPref *entry) { switch (entry->setting_type) { case G_TYPE_BOOLEAN: value->data.tree_int = *(gboolean *) entry->setting; break; case G_TYPE_INT: value->data.tree_int = *(gint *) entry->setting; break; case G_TYPE_STRING: SETPTR(value->data.tree_string, g_strdup(*(gchararray *) entry->setting)); break; default: g_warning("Unhandled type for %s::%s in %s()!", value->group_name, entry->key_name, G_STRFUNC); } } static void stash_tree_update_pref(StashTreeValue *value, StashPref *entry) { switch (entry->setting_type) { case G_TYPE_BOOLEAN: *(gboolean *) entry->setting = value->data.tree_int; break; case G_TYPE_INT: *(gint *) entry->setting = value->data.tree_int; break; case G_TYPE_STRING: { gchararray *text = entry->setting; SETPTR(*text, g_strdup(value->data.tree_string)); break; } default: g_warning("Unhandled type for %s::%s in %s()!", value->group_name, entry->key_name, G_STRFUNC); } } static void stash_tree_action(GtkTreeModel *model, PrefAction action) { GtkTreeIter iter; gboolean valid = gtk_tree_model_get_iter_first(model, &iter); StashTreeValue *value; while (valid) { gtk_tree_model_get(model, &iter, STASH_TREE_VALUE, &value, -1); switch (action) { case PREF_DISPLAY: stash_tree_display_pref(value, value->pref); break; case PREF_UPDATE: stash_tree_update_pref(value, value->pref); break; } valid = gtk_tree_model_iter_next(model, &iter); } } void stash_tree_display(GtkTreeView *tree) { stash_tree_action(gtk_tree_view_get_model(tree), PREF_DISPLAY); } void stash_tree_update(GtkTreeView *tree) { stash_tree_action(gtk_tree_view_get_model(tree), PREF_UPDATE); } geany-2.0/src/prefs.h0000644000175000017500000000401214514252267011463 00000000000000/* * prefs.h - this file is part of Geany, a fast and lightweight IDE * * Copyright 2005 The Geany contributors * * This program 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; either version 2 of the License, or * (at your option) any later version. * * This program 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef GEANY_PREFS_H #define GEANY_PREFS_H 1 #include G_BEGIN_DECLS /** General Preferences dialog settings. */ typedef struct GeanyPrefs { gboolean load_session; gboolean load_plugins; gboolean save_winpos; gboolean confirm_exit; gboolean beep_on_errors; /* use utils_beep() instead */ gboolean suppress_status_messages; gboolean switch_to_status; gboolean auto_focus; gchar *default_open_path; /**< Default path to look for files when no other path is appropriate. */ gchar *custom_plugin_path; gboolean save_wingeom; #ifdef G_OS_WIN32 gint socket_remote_cmd_port; #endif } GeanyPrefs; /** Tools preferences */ typedef struct GeanyToolPrefs { gchar *browser_cmd; /**< web browser command */ gchar *term_cmd; /**< terminal emulator command */ gchar *grep_cmd; /**< grep command */ gchar *context_action_cmd; /**< context action command */ } GeanyToolPrefs; #ifdef GEANY_PRIVATE extern GeanyPrefs prefs; extern GeanyToolPrefs tool_prefs; void prefs_show_dialog(void); void prefs_kb_search_name(const gchar *search); #endif /* GEANY_PRIVATE */ G_END_DECLS #endif /* GEANY_PREFS_H */ geany-2.0/src/editor.h0000644000175000017500000002514114514252267011640 00000000000000/* * editor.h - this file is part of Geany, a fast and lightweight IDE * * Copyright 2005 The Geany contributors * * This program 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; either version 2 of the License, or * (at your option) any later version. * * This program 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef GEANY_EDITOR_H #define GEANY_EDITOR_H 1 #include "tm_tag.h" /* for TMTag */ #include "gtkcompat.h" /* Needed by ScintillaWidget.h */ #include "Scintilla.h" /* Needed by ScintillaWidget.h */ #include "ScintillaWidget.h" /* for ScintillaObject */ #include G_BEGIN_DECLS /* Forward-declared to avoid including document.h since it includes this header */ struct GeanyDocument; /** Default character set to define which characters should be treated as part of a word. */ #define GEANY_WORDCHARS "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" #define GEANY_MAX_WORD_LENGTH 192 /** Whether to use tabs, spaces or both to indent. */ typedef enum { GEANY_INDENT_TYPE_SPACES, /**< Spaces. */ GEANY_INDENT_TYPE_TABS, /**< Tabs. */ GEANY_INDENT_TYPE_BOTH /**< Both. */ } GeanyIndentType; /** @gironly * Auto indentation modes */ typedef enum { GEANY_AUTOINDENT_NONE = 0, GEANY_AUTOINDENT_BASIC, GEANY_AUTOINDENT_CURRENTCHARS, GEANY_AUTOINDENT_MATCHBRACES } GeanyAutoIndent; /** Geany indicator types, can be used with Editor indicator functions to highlight * text in the document. */ typedef enum { /** Indicator to highlight errors in the document text. This is a red squiggly underline. */ GEANY_INDICATOR_ERROR = 0, /** Indicator used to highlight search results in the document. This is a * rounded box around the text. */ /* start container indicator outside of lexer indicators (0..7), see Scintilla docs */ GEANY_INDICATOR_SEARCH = 8, GEANY_INDICATOR_SNIPPET = 9 } GeanyIndicator; /** Indentation prefs that might be different according to project or filetype. * Use @c editor_get_indent_prefs() to lookup the prefs for a particular document. * * @since 0.15 **/ typedef struct GeanyIndentPrefs { gint width; /**< Indent width. */ GeanyIndentType type; /**< Whether to use tabs, spaces or both to indent. */ /** Width of a tab, but only when using GEANY_INDENT_TYPE_BOTH. * To get the display tab width, use sci_get_tab_width(). */ gint hard_tab_width; GeanyAutoIndent auto_indent_mode; gboolean detect_type; gboolean detect_width; } GeanyIndentPrefs; /** Default prefs when creating a new editor window. * Some of these can be overridden per document or per project. */ /* @warning Use @c editor_get_prefs() instead to include project overrides. */ typedef struct GeanyEditorPrefs { GeanyIndentPrefs *indentation; /* Default indentation prefs. Use editor_get_indent_prefs(). */ gboolean show_white_space; gboolean show_indent_guide; gboolean show_line_endings; /* 0 - line, 1 - background, 2 - disabled. */ gint long_line_type; gint long_line_column; gchar *long_line_color; gboolean show_markers_margin; /* view menu */ gboolean show_linenumber_margin; /* view menu */ gboolean show_scrollbars; /* hidden pref */ gboolean scroll_stop_at_last_line; gboolean line_wrapping; gboolean use_indicators; gboolean folding; gboolean unfold_all_children; gboolean disable_dnd; gboolean use_tab_to_indent; /* makes tab key indent instead of insert a tab char */ gboolean backspace_unindent; /* makes backspace char unindent instead of deleting one char */ gboolean smart_home_key; gboolean newline_strip; gboolean auto_complete_symbols; gboolean auto_close_xml_tags; gboolean complete_snippets; gint symbolcompletion_min_chars; gint symbolcompletion_max_height; gboolean brace_match_ltgt; /* whether to highlight < and > chars (hidden pref) */ gboolean use_gtk_word_boundaries; /* hidden pref */ gboolean complete_snippets_whilst_editing; /* hidden pref */ gint line_break_column; gboolean auto_continue_multiline; gchar *comment_toggle_mark; guint autocompletion_max_entries; guint autoclose_chars; gboolean autocomplete_doc_words; gboolean completion_drops_rest_of_word; gchar *color_scheme; gint show_virtual_space; gboolean long_line_enabled; gint autocompletion_update_freq; gint scroll_lines_around_cursor; gint ime_interaction; /* input method editor's candidate window behaviour */ gboolean show_line_endings_only_when_differ; gboolean change_history_markers; gboolean change_history_indicators; } GeanyEditorPrefs; #define GEANY_TYPE_EDITOR (editor_get_type()) GType editor_get_type (void); /** Editor-owned fields for each document. */ typedef struct GeanyEditor { struct GeanyDocument *document; /**< The document associated with the editor. */ ScintillaObject *sci; /**< The Scintilla editor @c GtkWidget. */ gboolean line_wrapping; /**< @c TRUE if line wrapping is enabled. */ gboolean auto_indent; /**< @c TRUE if auto-indentation is enabled. */ /** Percentage to scroll view by on paint, if positive. */ gfloat scroll_percent; GeanyIndentType indent_type; /* Use editor_get_indent_prefs() instead. */ gboolean line_breaking; /**< Whether to split long lines as you type. */ gint indent_width; } GeanyEditor; const GeanyIndentPrefs *editor_get_indent_prefs(GeanyEditor *editor); ScintillaObject *editor_create_widget(GeanyEditor *editor); void editor_indicator_set_on_range(GeanyEditor *editor, gint indic, gint start, gint end); void editor_indicator_set_on_line(GeanyEditor *editor, gint indic, gint line); void editor_indicator_clear(GeanyEditor *editor, gint indic); void editor_set_indent_type(GeanyEditor *editor, GeanyIndentType type); void editor_set_indent_width(GeanyEditor *editor, gint width); gchar *editor_get_word_at_pos(GeanyEditor *editor, gint pos, const gchar *wordchars); const gchar *editor_get_eol_char_name(GeanyEditor *editor); gint editor_get_eol_char_len(GeanyEditor *editor); const gchar *editor_get_eol_char(GeanyEditor *editor); void editor_insert_text_block(GeanyEditor *editor, const gchar *text, gint insert_pos, gint cursor_index, gint newline_indent_size, gboolean replace_newlines); gint editor_get_eol_char_mode(GeanyEditor *editor); gboolean editor_goto_pos(GeanyEditor *editor, gint pos, gboolean mark); const gchar *editor_find_snippet(GeanyEditor *editor, const gchar *snippet_name); void editor_insert_snippet(GeanyEditor *editor, gint pos, const gchar *snippet); #ifdef GEANY_PRIVATE extern GeanyEditorPrefs editor_prefs; typedef enum { GEANY_VIRTUAL_SPACE_DISABLED = 0, GEANY_VIRTUAL_SPACE_SELECTION = 1, GEANY_VIRTUAL_SPACE_ALWAYS = 3 } GeanyVirtualSpace; /* Auto-close brackets/quotes */ enum { GEANY_AC_PARENTHESIS = 1, GEANY_AC_CBRACKET = 2, GEANY_AC_SBRACKET = 4, GEANY_AC_SQUOTE = 8, GEANY_AC_DQUOTE = 16 }; typedef struct { gchar *current_word; /* holds word under the mouse or keyboard cursor */ gint click_pos; /* text position where the mouse was clicked */ } EditorInfo; extern EditorInfo editor_info; void editor_init(void); GeanyEditor *editor_create(struct GeanyDocument *doc); void editor_destroy(GeanyEditor *editor); void editor_sci_notify_cb(GtkWidget *widget, gint scn, gpointer scnt, gpointer data); gboolean editor_start_auto_complete(GeanyEditor *editor, gint pos, gboolean force); gboolean editor_complete_word_part(GeanyEditor *editor); gboolean editor_goto_next_snippet_cursor(GeanyEditor *editor); gboolean editor_complete_snippet(GeanyEditor *editor, gint pos); gboolean editor_show_calltip(GeanyEditor *editor, gint pos); void editor_do_comment_toggle(GeanyEditor *editor); gint editor_do_comment(GeanyEditor *editor, gint line, gboolean allow_empty_lines, gboolean toggle, gboolean single_comment); gint editor_do_uncomment(GeanyEditor *editor, gint line, gboolean toggle); void editor_insert_multiline_comment(GeanyEditor *editor); void editor_insert_alternative_whitespace(GeanyEditor *editor); void editor_indent(GeanyEditor *editor, gboolean increase); void editor_smart_line_indentation(GeanyEditor *editor); void editor_indentation_by_one_space(GeanyEditor *editor, gint pos, gboolean decrease); gboolean editor_line_in_view(GeanyEditor *editor, gint line); void editor_scroll_to_line(GeanyEditor *editor, gint line, gfloat percent_of_view); void editor_display_current_line(GeanyEditor *editor, gfloat percent_of_view); void editor_finalize(void); void editor_snippets_init(void); void editor_snippets_free(void); const GeanyEditorPrefs *editor_get_prefs(GeanyEditor *editor); /* General editing functions */ void editor_find_current_word(GeanyEditor *editor, gint pos, gchar *word, gsize wordlen, const gchar *wc); void editor_find_current_word_sciwc(GeanyEditor *editor, gint pos, gchar *word, gsize wordlen); gchar *editor_get_default_selection(GeanyEditor *editor, gboolean use_current_word, const gchar *wordchars); void editor_select_word(GeanyEditor *editor); void editor_select_lines(GeanyEditor *editor, gboolean extra_line); void editor_select_paragraph(GeanyEditor *editor); void editor_select_indent_block(GeanyEditor *editor); void editor_set_font(GeanyEditor *editor, const gchar *font); void editor_indicator_clear_errors(GeanyEditor *editor); void editor_fold_all(GeanyEditor *editor); void editor_unfold_all(GeanyEditor *editor); void editor_replace_tabs(GeanyEditor *editor, gboolean ignore_selection); void editor_replace_spaces(GeanyEditor *editor, gboolean ignore_selection); void editor_strip_line_trailing_spaces(GeanyEditor *editor, gint line); void editor_strip_trailing_spaces(GeanyEditor *editor, gboolean ignore_selection); void editor_ensure_final_newline(GeanyEditor *editor); void editor_insert_color(GeanyEditor *editor, const gchar *colour); void editor_set_indent(GeanyEditor *editor, GeanyIndentType type, gint width); void editor_set_line_wrapping(GeanyEditor *editor, gboolean wrap); gboolean editor_goto_line(GeanyEditor *editor, gint line_no, gboolean offset); void editor_set_indentation_guides(GeanyEditor *editor); void editor_apply_update_prefs(GeanyEditor *editor); void editor_toggle_fold(GeanyEditor *editor, gint line, gint modifiers); #endif /* GEANY_PRIVATE */ G_END_DECLS #endif /* GEANY_EDITOR_H */ geany-2.0/src/spawn.h0000644000175000017500000001076714514252267011512 00000000000000/* * spawn.h - this file is part of Geany, a fast and lightweight IDE * * Copyright 2013 The Geany contributors * * This program 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; either version 2 of the License, or * (at your option) any later version. * * This program 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef GEANY_SPAWN_H #define GEANY_SPAWN_H 1 #include #ifdef G_OS_WIN32 # define SPAWN_WIFEXITED(status) TRUE # define SPAWN_WEXITSTATUS(status) (status) # define SPAWN_WIFSIGNALED(status) FALSE #else # include # include # define SPAWN_WIFEXITED(status) WIFEXITED(status) /**< non-zero if the child exited normally */ # define SPAWN_WEXITSTATUS(status) WEXITSTATUS(status) /**< exit status of a child if exited normally */ # define SPAWN_WIFSIGNALED(status) WIFSIGNALED(status) /**< non-zero if the child exited due to signal */ #endif G_BEGIN_DECLS gboolean spawn_check_command(const gchar *command_line, gboolean execute, GError **error); gboolean spawn_kill_process(GPid pid, GError **error); gboolean spawn_async(const gchar *working_directory, const gchar *command_line, gchar **argv, gchar **envp, GPid *child_pid, GError **error); /** Flags passed to @c spawn_with_callbacks(), which see. */ typedef enum { SPAWN_ASYNC = 0x00, /**< Asynchronous execution [default]. */ SPAWN_SYNC = 0x01, /**< Synchronous execution. */ /* buffering modes */ SPAWN_LINE_BUFFERED = 0x00, /**< stdout/stderr are line buffered [default]. */ SPAWN_STDOUT_UNBUFFERED = 0x02, /**< stdout is not buffered. */ SPAWN_STDERR_UNBUFFERED = 0x04, /**< stderr is not buffered. */ SPAWN_UNBUFFERED = 0x06, /**< stdout/stderr are not buffered. */ /* recursive modes */ SPAWN_STDIN_RECURSIVE = 0x08, /**< The stdin callback is recursive. */ SPAWN_STDOUT_RECURSIVE = 0x10, /**< The stdout callback is recursive. */ SPAWN_STDERR_RECURSIVE = 0x20, /**< The stderr callback is recursive. */ SPAWN_RECURSIVE = 0x38 /**< All callbacks are recursive. */ } SpawnFlags; /** * Specifies the type of function passed to @c spawn_with_callbacks() as stdout or stderr * callback. * * In unbuffered mode, the @a string may contain nuls, while in line buffered mode, it may * contain only a single nul as a line termination character at @a string->len - 1. In all * cases, the @a string will be terminated with a nul character that is not part of the data * at @a string->len. * * If @c G_IO_IN or @c G_IO_PRI are set, the @a string will contain at least one character. * * @param string contains the child data if @c G_IO_IN or @c G_IO_PRI are set. * @param condition the I/O condition which has been satisfied. * @param data the passed to @c spawn_with_callbacks() with the callback. */ typedef void (*SpawnReadFunc)(GString *string, GIOCondition condition, gpointer data); gboolean spawn_with_callbacks(const gchar *working_directory, const gchar *command_line, gchar **argv, gchar **envp, SpawnFlags spawn_flags, GIOFunc stdin_cb, gpointer stdin_data, SpawnReadFunc stdout_cb, gpointer stdout_data, gsize stdout_max_length, SpawnReadFunc stderr_cb, gpointer stderr_data, gsize stderr_max_length, GChildWatchFunc exit_cb, gpointer exit_data, GPid *child_pid, GError **error); /** * A simple structure used by @c spawn_write_data() to write data to a channel. * See @c spawn_write_data() for more information. */ typedef struct _SpawnWriteData { const gchar *ptr; /**< Pointer to the data. May be NULL if the size is 0. */ gsize size; /**< Size of the data. */ } SpawnWriteData; gboolean spawn_write_data(GIOChannel *channel, GIOCondition condition, SpawnWriteData *data); gboolean spawn_sync(const gchar *working_directory, const gchar *command_line, gchar **argv, gchar **envp, SpawnWriteData *stdin_data, GString *stdout_data, GString *stderr_data, gint *exit_status, GError **error); G_END_DECLS #endif /* GEANY_SPAWN_H */ geany-2.0/src/geanyentryaction.c0000644000175000017500000001307014514252267013726 00000000000000/* * geanyentryaction.c - this file is part of Geany, a fast and lightweight IDE * * Copyright 2008 The Geany contributors * * This program 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; either version 2 of the License, or * (at your option) any later version. * * This program 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /* GtkAction subclass to provide a GtkEntry in a toolbar. * This class is missing the action_create_menu_item() function and so can't be * used for creating menu items. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include "geanyentryaction.h" #include "ui_utils.h" #include typedef struct _GeanyEntryActionPrivate GeanyEntryActionPrivate; #define GEANY_ENTRY_ACTION_GET_PRIVATE(obj) (GEANY_ENTRY_ACTION(obj)->priv) struct _GeanyEntryActionPrivate { GtkWidget *entry; gboolean numeric; gboolean connected; }; enum { ENTRY_ACTIVATE, ENTRY_ACTIVATE_BACKWARD, ENTRY_CHANGED, LAST_SIGNAL }; static guint signals[LAST_SIGNAL]; G_DEFINE_TYPE(GeanyEntryAction, geany_entry_action, GTK_TYPE_ACTION) static GtkWidget *geany_entry_action_create_tool_item(GtkAction *action) { GtkWidget *toolitem; GeanyEntryActionPrivate *priv = GEANY_ENTRY_ACTION_GET_PRIVATE(action); priv->entry = gtk_entry_new(); if (priv->numeric) gtk_entry_set_width_chars(GTK_ENTRY(priv->entry), 9); ui_entry_add_clear_icon(GTK_ENTRY(priv->entry)); ui_entry_add_activate_backward_signal(GTK_ENTRY(priv->entry)); gtk_widget_show(priv->entry); toolitem = g_object_new(GTK_TYPE_TOOL_ITEM, NULL); gtk_container_add(GTK_CONTAINER(toolitem), priv->entry); return toolitem; } static void delegate_entry_activate_cb(GtkEntry *entry, GeanyEntryAction *action) { GeanyEntryActionPrivate *priv = GEANY_ENTRY_ACTION_GET_PRIVATE(action); const gchar *text = gtk_entry_get_text(GTK_ENTRY(priv->entry)); g_signal_emit(action, signals[ENTRY_ACTIVATE], 0, text); } static void delegate_entry_activate_backward_cb(GtkEntry *entry, GeanyEntryAction *action) { GeanyEntryActionPrivate *priv = GEANY_ENTRY_ACTION_GET_PRIVATE(action); const gchar *text = gtk_entry_get_text(GTK_ENTRY(priv->entry)); g_signal_emit(action, signals[ENTRY_ACTIVATE_BACKWARD], 0, text); } static void delegate_entry_changed_cb(GtkEditable *editable, GeanyEntryAction *action) { GeanyEntryActionPrivate *priv = GEANY_ENTRY_ACTION_GET_PRIVATE(action); const gchar *text = gtk_entry_get_text(GTK_ENTRY(priv->entry)); g_signal_emit(action, signals[ENTRY_CHANGED], 0, text); } static void geany_entry_action_connect_proxy(GtkAction *action, GtkWidget *widget) { GeanyEntryActionPrivate *priv = GEANY_ENTRY_ACTION_GET_PRIVATE(action); /* make sure not to connect handlers twice */ if (! priv->connected) { if (priv->numeric) g_signal_connect(priv->entry, "insert-text", G_CALLBACK(ui_editable_insert_text_callback), NULL); g_signal_connect(priv->entry, "changed", G_CALLBACK(delegate_entry_changed_cb), action); g_signal_connect(priv->entry, "activate", G_CALLBACK(delegate_entry_activate_cb), action); g_signal_connect(priv->entry, "activate-backward", G_CALLBACK(delegate_entry_activate_backward_cb), action); priv->connected = TRUE; } GTK_ACTION_CLASS(geany_entry_action_parent_class)->connect_proxy(action, widget); } static void geany_entry_action_class_init(GeanyEntryActionClass *klass) { GtkActionClass *action_class = GTK_ACTION_CLASS(klass); action_class->connect_proxy = geany_entry_action_connect_proxy; action_class->create_tool_item = geany_entry_action_create_tool_item; action_class->toolbar_item_type = GTK_TYPE_MENU_TOOL_BUTTON; g_type_class_add_private(klass, sizeof(GeanyEntryActionPrivate)); signals[ENTRY_CHANGED] = g_signal_new("entry-changed", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__STRING, G_TYPE_NONE, 1, G_TYPE_STRING); signals[ENTRY_ACTIVATE] = g_signal_new("entry-activate", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__STRING, G_TYPE_NONE, 1, G_TYPE_STRING); signals[ENTRY_ACTIVATE_BACKWARD] = g_signal_new("entry-activate-backward", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__STRING, G_TYPE_NONE, 1, G_TYPE_STRING); } static void geany_entry_action_init(GeanyEntryAction *action) { GeanyEntryActionPrivate *priv; action->priv = G_TYPE_INSTANCE_GET_PRIVATE(action, GEANY_ENTRY_ACTION_TYPE, GeanyEntryActionPrivate); priv = action->priv; priv->entry = NULL; priv->numeric = FALSE; priv->connected = FALSE; } GtkAction *geany_entry_action_new(const gchar *name, const gchar *label, const gchar *tooltip, gboolean numeric) { GtkAction *action = g_object_new(GEANY_ENTRY_ACTION_TYPE, "name", name, "label", label, "tooltip", tooltip, NULL); GeanyEntryActionPrivate *priv = GEANY_ENTRY_ACTION_GET_PRIVATE(action); priv->numeric = numeric; return action; } geany-2.0/src/search.h0000644000175000017500000001013314514252267011612 00000000000000/* * search.h - this file is part of Geany, a fast and lightweight IDE * * Copyright 2006 The Geany contributors * * This program 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; either version 2 of the License, or * (at your option) any later version. * * This program 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /** * @file search.h * Search (prefs). **/ #ifndef GEANY_SEARCH_H #define GEANY_SEARCH_H 1 #include G_BEGIN_DECLS typedef enum GeanyFindFlags { GEANY_FIND_MATCHCASE = 1 << 0, GEANY_FIND_WHOLEWORD = 1 << 1, GEANY_FIND_WORDSTART = 1 << 2, GEANY_FIND_REGEXP = 1 << 3, GEANY_FIND_MULTILINE = 1 << 4 } GeanyFindFlags; /** @gironly * Find selection options */ typedef enum { GEANY_FIND_SEL_CURRENT_WORD, GEANY_FIND_SEL_X, GEANY_FIND_SEL_AGAIN } GeanyFindSelOptions; /** Search preferences */ typedef struct GeanySearchPrefs { gboolean always_wrap; /* don't ask whether to wrap search */ gboolean use_current_word; /**< Use current word for default search text */ gboolean use_current_file_dir; /* find in files directory to use on showing dialog */ gboolean hide_find_dialog; /* hide the find dialog on next or previous */ gboolean replace_and_find_by_default; /* enter in replace window performs Replace & Find instead of Replace */ GeanyFindSelOptions find_selection_type; } GeanySearchPrefs; typedef struct GeanyMatchInfo { GeanyFindFlags flags; /* range */ gint start, end; /* only valid if (flags & GEANY_FIND_REGEX) */ gchar *match_text; /* text actually matched */ struct { gint start, end; } matches[10]; /* sub-patterns */ } GeanyMatchInfo; void search_show_find_in_files_dialog(const gchar *dir); #ifdef GEANY_PRIVATE struct GeanyDocument; /* document.h includes this header */ struct _ScintillaObject; struct Sci_TextToFind; /* the flags given in the search dialog for "find next", also used by the search bar */ typedef struct GeanySearchData { gchar *text; GeanyFindFlags flags; gboolean backwards; /* set to TRUE when text was set by a search bar callback to keep track of * search bar background colour */ gboolean search_bar; /* text as it was entered by user */ gchar *original_text; } GeanySearchData; extern GeanySearchData search_data; extern GeanySearchPrefs search_prefs; void search_init(void); void search_finalize(void); void search_show_find_dialog(void); void search_show_replace_dialog(void); void search_show_find_in_files_dialog_full(const gchar *text, const gchar *dir); void geany_match_info_free(GeanyMatchInfo *info); gint search_find_prev(struct _ScintillaObject *sci, const gchar *str, GeanyFindFlags flags, GeanyMatchInfo **match_); gint search_find_next(struct _ScintillaObject *sci, const gchar *str, GeanyFindFlags flags, GeanyMatchInfo **match_); gint search_find_text(struct _ScintillaObject *sci, GeanyFindFlags flags, struct Sci_TextToFind *ttf, GeanyMatchInfo **match_); void search_find_again(gboolean change_direction); void search_find_usage(const gchar *search_text, const gchar *original_search_text, GeanyFindFlags flags, gboolean in_session); void search_find_selection(struct GeanyDocument *doc, gboolean search_backwards); gint search_mark_all(struct GeanyDocument *doc, const gchar *search_text, GeanyFindFlags flags); gint search_replace_match(struct _ScintillaObject *sci, const GeanyMatchInfo *match, const gchar *replace_text); guint search_replace_range(struct _ScintillaObject *sci, struct Sci_TextToFind *ttf, GeanyFindFlags flags, const gchar *replace_text); #endif /* GEANY_PRIVATE */ G_END_DECLS #endif /* GEANY_SEARCH_H */ geany-2.0/src/geanywraplabel.h0000644000175000017500000000334714514252267013353 00000000000000/* * geanywraplabel.h - this file is part of Geany, a fast and lightweight IDE * * Copyright 2009 The Geany contributors * * This program 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; either version 2 of the License, or * (at your option) any later version. * * This program 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef GEANY_WRAP_LABEL_H #define GEANY_WRAP_LABEL_H 1 #include "gtkcompat.h" G_BEGIN_DECLS #define GEANY_WRAP_LABEL_TYPE (geany_wrap_label_get_type()) #define GEANY_WRAP_LABEL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), \ GEANY_WRAP_LABEL_TYPE, GeanyWrapLabel)) #define GEANY_WRAP_LABEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), \ GEANY_WRAP_LABEL_TYPE, GeanyWrapLabelClass)) #define IS_GEANY_WRAP_LABEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), \ GEANY_WRAP_LABEL_TYPE)) #define IS_GEANY_WRAP_LABEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), \ GEANY_WRAP_LABEL_TYPE)) typedef struct _GeanyWrapLabel GeanyWrapLabel; typedef struct _GeanyWrapLabelClass GeanyWrapLabelClass; GType geany_wrap_label_get_type (void); GtkWidget* geany_wrap_label_new (const gchar *text); G_END_DECLS #endif /* GEANY_WRAP_LABEL_H */ geany-2.0/src/log.c0000644000175000017500000001361414514252267011130 00000000000000/* * log.c - this file is part of Geany, a fast and lightweight IDE * * Copyright 2008 The Geany contributors * * This program 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; either version 2 of the License, or * (at your option) any later version. * * This program 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /* * Logging functions and the debug messages window. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include "log.h" #include "app.h" #include "support.h" #include "utils.h" #include "ui_utils.h" #include #ifdef HAVE_LOCALE_H # include #endif static GString *log_buffer = NULL; static GtkTextBuffer *dialog_textbuffer = NULL; enum { DIALOG_RESPONSE_CLEAR = 1 }; static void update_dialog(void) { if (dialog_textbuffer != NULL) { GtkTextMark *mark; GtkTextView *textview = g_object_get_data(G_OBJECT(dialog_textbuffer), "textview"); gtk_text_buffer_set_text(dialog_textbuffer, log_buffer->str, log_buffer->len); /* scroll to the end of the messages as this might be most interesting */ mark = gtk_text_buffer_get_insert(dialog_textbuffer); gtk_text_view_scroll_to_mark(textview, mark, 0.0, FALSE, 0.0, 0.0); } } /* Geany's main debug/log function, declared in geany.h */ void geany_debug(gchar const *format, ...) { va_list args; va_start(args, format); g_logv(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, format, args); va_end(args); } static void handler_print(const gchar *msg) { printf("%s", msg); if (G_LIKELY(log_buffer != NULL)) { g_string_append_printf(log_buffer, "%s", msg); update_dialog(); } } static void handler_printerr(const gchar *msg) { fprintf(stderr, "%s", msg); if (G_LIKELY(log_buffer != NULL)) { g_string_append_printf(log_buffer, "%s", msg); update_dialog(); } } static const gchar *get_log_prefix(GLogLevelFlags log_level) { switch (log_level & G_LOG_LEVEL_MASK) { case G_LOG_LEVEL_ERROR: return "ERROR\t\t"; case G_LOG_LEVEL_CRITICAL: return "CRITICAL\t"; case G_LOG_LEVEL_WARNING: return "WARNING\t"; case G_LOG_LEVEL_MESSAGE: return "MESSAGE\t"; case G_LOG_LEVEL_INFO: return "INFO\t\t"; case G_LOG_LEVEL_DEBUG: return "DEBUG\t"; } return "LOG"; } static void handler_log(const gchar *domain, GLogLevelFlags level, const gchar *msg, gpointer data) { gchar *time_str; if (G_LIKELY(app != NULL && app->debug_mode) || ! ((G_LOG_LEVEL_DEBUG | G_LOG_LEVEL_INFO | G_LOG_LEVEL_MESSAGE) & level)) { #ifdef G_OS_WIN32 /* On Windows g_log_default_handler() is not enough, we need to print it * explicitly on stderr for the console window */ /** TODO this can be removed if/when we remove the console window on Windows */ if (domain != NULL) fprintf(stderr, "%s: %s\n", domain, msg); else fprintf(stderr, "%s\n", msg); #else /* print the message as usual on stdout/stderr */ g_log_default_handler(domain, level, msg, data); #endif } time_str = utils_get_current_time_string(TRUE); g_string_append_printf(log_buffer, "%s: %s %s: %s\n", time_str, domain, get_log_prefix(level), msg); g_free(time_str); update_dialog(); } void log_handlers_init(void) { log_buffer = g_string_sized_new(2048); g_set_print_handler(handler_print); g_set_printerr_handler(handler_printerr); g_log_set_default_handler(handler_log, NULL); } static void on_dialog_response(GtkDialog *dialog, gint response, gpointer user_data) { if (response == DIALOG_RESPONSE_CLEAR) { GtkTextIter start_iter, end_iter; gtk_text_buffer_get_start_iter(dialog_textbuffer, &start_iter); gtk_text_buffer_get_end_iter(dialog_textbuffer, &end_iter); gtk_text_buffer_delete(dialog_textbuffer, &start_iter, &end_iter); g_string_erase(log_buffer, 0, -1); } else { gtk_widget_destroy(GTK_WIDGET(dialog)); dialog_textbuffer = NULL; } } void log_show_debug_messages_dialog(void) { GtkWidget *dialog, *textview, *vbox, *swin; dialog = gtk_dialog_new_with_buttons(_("Debug Messages"), GTK_WINDOW(main_widgets.window), GTK_DIALOG_DESTROY_WITH_PARENT, _("Cl_ear"), DIALOG_RESPONSE_CLEAR, GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, NULL); vbox = ui_dialog_vbox_new(GTK_DIALOG(dialog)); gtk_box_set_spacing(GTK_BOX(vbox), 6); gtk_widget_set_name(dialog, "GeanyDialog"); gtk_window_set_default_size(GTK_WINDOW(dialog), 550, 300); gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_CLOSE); textview = gtk_text_view_new(); dialog_textbuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview)); g_object_set_data(G_OBJECT(dialog_textbuffer), "textview", textview); gtk_text_view_set_editable(GTK_TEXT_VIEW(textview), FALSE); gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(textview), FALSE); gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(textview), GTK_WRAP_WORD_CHAR); swin = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(swin), GTK_SHADOW_IN); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(swin), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_container_add(GTK_CONTAINER(swin), textview); gtk_box_pack_start(GTK_BOX(vbox), swin, TRUE, TRUE, 0); g_signal_connect(dialog, "response", G_CALLBACK(on_dialog_response), textview); gtk_widget_show_all(dialog); update_dialog(); /* set text after showing the window, to not scroll an unrealized textview */ } void log_finalize(void) { g_log_set_default_handler(g_log_default_handler, NULL); g_string_free(log_buffer, TRUE); log_buffer = NULL; } geany-2.0/src/keyfile.h0000644000175000017500000000377714514252267012015 00000000000000/* * keyfile.h - this file is part of Geany, a fast and lightweight IDE * * Copyright 2005 The Geany contributors * * This program 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; either version 2 of the License, or * (at your option) any later version. * * This program 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef GEANY_KEYFILE_H #define GEANY_KEYFILE_H 1 #include G_BEGIN_DECLS extern GPtrArray *pref_groups; void configuration_init(void); void configuration_finalize(void); struct StashGroup; void configuration_add_pref_group(struct StashGroup *group, gboolean for_prefs_dialog); void configuration_add_various_pref_group(struct StashGroup *group, const gchar *prefix); void configuration_add_session_group(struct StashGroup *group, gboolean for_prefs_dialog); void configuration_save(void); gboolean configuration_load(void); void configuration_open_files(GPtrArray *session_files); void configuration_load_default_session(void); void configuration_open_default_session(void); void configuration_save_default_session(void); void configuration_clear_default_session(void); GPtrArray *configuration_load_session_files(GKeyFile *config); void configuration_save_session_files(GKeyFile *config); /* set some settings which are already read from the config file, but need other things, like the * realisation of the main window */ void configuration_apply_settings(void); G_END_DECLS #endif /* GEANY_KEYFILE_H */ geany-2.0/src/printing.c0000644000175000017500000005243714514252267012207 00000000000000/* * printing.c - this file is part of Geany, a fast and lightweight IDE * * Copyright 2007 The Geany contributors * * This program 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; either version 2 of the License, or * (at your option) any later version. * * This program 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /* * GTK printing support * (basic code layout were adopted from Sylpheed's printing implementation, thanks) */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include "printing.h" #include "app.h" #include "dialogs.h" #include "document.h" #include "geany.h" #include "highlighting.h" #include "msgwindow.h" #include "sciwrappers.h" #include "spawn.h" #include "support.h" #include "utils.h" #include "ui_utils.h" #include #include #include PrintingPrefs printing_prefs; /* document-related variables */ typedef struct { GeanyDocument *doc; ScintillaObject *sci; gdouble margin_width; gdouble line_height; /* set in begin_print() to hold the time when printing was started to ensure all printed * pages have the same date and time (in case of slow machines and many pages where rendering * takes more than a second) */ time_t print_time; PangoLayout *layout; /* commonly used layout object */ gdouble sci_scale; struct Sci_RangeToFormat fr; GArray *pages; } DocInfo; /* widget references for the custom widget in the print dialog */ typedef struct { GtkWidget *check_print_linenumbers; GtkWidget *check_print_pagenumbers; GtkWidget *check_print_pageheader; GtkWidget *check_print_basename; GtkWidget *entry_print_dateformat; } PrintWidgets; static GtkPrintSettings *settings = NULL; static GtkPageSetup *page_setup = NULL; /* creates a commonly used layout object from the given context for use in get_page_count and * draw_page */ static PangoLayout *setup_pango_layout(GtkPrintContext *context, PangoFontDescription *desc) { PangoLayout *layout; layout = gtk_print_context_create_pango_layout(context); pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR); pango_layout_set_spacing(layout, 0); pango_layout_set_attributes(layout, NULL); pango_layout_set_font_description(layout, desc); return layout; } static void get_text_dimensions(PangoLayout *layout, const gchar *text, gdouble *width, gdouble *height) { gint layout_w, layout_h; pango_layout_set_text(layout, text, -1); pango_layout_get_size(layout, &layout_w, &layout_h); if (layout_w <= 0) { gint default_w = 50 * strlen(text) * PANGO_SCALE; geany_debug("Invalid layout_w (%d). Falling back to default width (%d)", layout_w, default_w); layout_w = default_w; } if (layout_h <= 0) { gint default_h = 100 * PANGO_SCALE; geany_debug("Invalid layout_h (%d). Falling back to default height (%d)", layout_h, default_h); layout_h = default_h; } if (width) *width = (gdouble)layout_w / PANGO_SCALE; if (height) *height = (gdouble)layout_h / PANGO_SCALE; } static void add_page_header(DocInfo *dinfo, cairo_t *cr, gint width, gint page_nr) { gint ph_height = dinfo->line_height * 3; gchar *data; gchar *datetime; const gchar *tmp_file_name = DOC_FILENAME(dinfo->doc); gchar *file_name = (printing_prefs.page_header_basename) ? g_path_get_basename(tmp_file_name) : g_strdup(tmp_file_name); PangoLayout *layout = dinfo->layout; /* draw the frame */ cairo_set_line_width(cr, 0.3); cairo_set_source_rgb(cr, 0, 0, 0); cairo_rectangle(cr, 2, 2, width - 4, ph_height - 4); cairo_stroke(cr); /* width - 8: 2px between doc border and frame border, 2px between frame border and text * and this on left and right side, so (2 + 2) * 2 */ pango_layout_set_width(layout, (width - 8) * PANGO_SCALE); pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_MIDDLE); data = g_strdup_printf("%s", file_name); pango_layout_set_markup(layout, data, -1); pango_layout_set_alignment(layout, PANGO_ALIGN_LEFT); cairo_move_to(cr, 4, dinfo->line_height * 0.5); pango_cairo_show_layout(cr, layout); g_free(data); g_free(file_name); data = g_strdup_printf(_("Page %d of %d"), page_nr + 1, dinfo->pages->len); pango_layout_set_markup(layout, data, -1); pango_layout_set_alignment(layout, PANGO_ALIGN_LEFT); cairo_move_to(cr, 4, dinfo->line_height * 1.5); pango_cairo_show_layout(cr, layout); g_free(data); datetime = utils_get_date_time(printing_prefs.page_header_datefmt, &(dinfo->print_time)); if (G_LIKELY(!EMPTY(datetime))) { data = g_strdup_printf("%s", datetime); pango_layout_set_markup(layout, data, -1); pango_layout_set_alignment(layout, PANGO_ALIGN_RIGHT); cairo_move_to(cr, 2, dinfo->line_height * 1.5); pango_cairo_show_layout(cr, layout); g_free(data); } g_free(datetime); /* reset layout and re-position cairo context */ pango_layout_set_alignment(layout, PANGO_ALIGN_LEFT); pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_NONE); pango_layout_set_justify(layout, FALSE); pango_layout_set_width(layout, width * PANGO_SCALE); cairo_move_to(cr, 0, dinfo->line_height * 3); } static void custom_widget_apply(GtkPrintOperation *operation, GtkWidget *widget, gpointer user_data) { PrintWidgets *w = user_data; printing_prefs.print_line_numbers = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w->check_print_linenumbers)); printing_prefs.print_page_numbers = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w->check_print_pagenumbers)); printing_prefs.print_page_header = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w->check_print_pageheader)); printing_prefs.page_header_basename = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w->check_print_basename)); g_free(printing_prefs.page_header_datefmt); printing_prefs.page_header_datefmt = g_strdup(gtk_entry_get_text(GTK_ENTRY(w->entry_print_dateformat))); } static void on_page_header_toggled(GtkToggleButton *togglebutton, gpointer user_data) { gboolean sens = gtk_toggle_button_get_active(togglebutton); PrintWidgets *w = user_data; gtk_widget_set_sensitive(w->check_print_basename, sens); gtk_widget_set_sensitive(w->entry_print_dateformat, sens); } static GtkWidget *create_custom_widget(GtkPrintOperation *operation, gpointer user_data) { /* copied from interface.c */ GtkWidget *page; GtkWidget *frame33; GtkWidget *alignment36; GtkWidget *vbox30; GtkWidget *hbox10; GtkWidget *label203; PrintWidgets *w = user_data; gtk_print_operation_set_custom_tab_label(operation, _("Document Setup")); page = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); gtk_container_set_border_width(GTK_CONTAINER(page), 5); w->check_print_linenumbers = gtk_check_button_new_with_mnemonic(_("Print line numbers")); gtk_box_pack_start(GTK_BOX(page), w->check_print_linenumbers, FALSE, FALSE, 0); gtk_widget_set_tooltip_text(w->check_print_linenumbers, _("Add line numbers to the printed page")); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w->check_print_linenumbers), printing_prefs.print_line_numbers); w->check_print_pagenumbers = gtk_check_button_new_with_mnemonic(_("Print page numbers")); gtk_box_pack_start(GTK_BOX(page), w->check_print_pagenumbers, FALSE, FALSE, 0); gtk_widget_set_tooltip_text(w->check_print_pagenumbers, _("Add page numbers at the bottom of each page. It takes 2 lines of the page.")); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w->check_print_pagenumbers), printing_prefs.print_page_numbers); w->check_print_pageheader = gtk_check_button_new_with_mnemonic(_("Print page header")); gtk_box_pack_start(GTK_BOX(page), w->check_print_pageheader, FALSE, FALSE, 0); gtk_widget_set_tooltip_text(w->check_print_pageheader, _("Add a little header to every page containing the page number, the filename and the current date (see below). It takes 3 lines of the page.")); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w->check_print_pageheader), printing_prefs.print_page_header); g_signal_connect(w->check_print_pageheader, "toggled", G_CALLBACK(on_page_header_toggled), w); frame33 = gtk_frame_new(NULL); gtk_box_pack_start(GTK_BOX(page), frame33, FALSE, FALSE, 0); gtk_frame_set_label_align(GTK_FRAME(frame33), 0, 0); gtk_frame_set_shadow_type(GTK_FRAME(frame33), GTK_SHADOW_NONE); alignment36 = gtk_alignment_new(0, 0.5, 1, 1); gtk_container_add(GTK_CONTAINER(frame33), alignment36); gtk_alignment_set_padding(GTK_ALIGNMENT(alignment36), 0, 0, 12, 0); vbox30 = gtk_box_new(GTK_ORIENTATION_VERTICAL, 1); gtk_container_add(GTK_CONTAINER(alignment36), vbox30); w->check_print_basename = gtk_check_button_new_with_mnemonic(_("Use the basename of the printed file")); gtk_box_pack_start(GTK_BOX(vbox30), w->check_print_basename, FALSE, FALSE, 0); gtk_widget_set_tooltip_text(w->check_print_basename, _("Print only the basename(without the path) of the printed file")); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w->check_print_basename), printing_prefs.page_header_basename); hbox10 = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5); gtk_box_pack_start(GTK_BOX(vbox30), hbox10, TRUE, TRUE, 0); label203 = gtk_label_new(_("Date format:")); gtk_box_pack_start(GTK_BOX(hbox10), label203, FALSE, FALSE, 0); w->entry_print_dateformat = gtk_entry_new(); ui_entry_add_clear_icon(GTK_ENTRY(w->entry_print_dateformat)); gtk_box_pack_start(GTK_BOX(hbox10), w->entry_print_dateformat, TRUE, TRUE, 0); gtk_widget_set_tooltip_text(w->entry_print_dateformat, _("Specify a format for the date and time stamp which is added to the page header on each page. For a list of available conversion specifiers see https://docs.gtk.org/glib/method.DateTime.format.html.")); gtk_entry_set_text(GTK_ENTRY(w->entry_print_dateformat), printing_prefs.page_header_datefmt); on_page_header_toggled(GTK_TOGGLE_BUTTON(w->check_print_pageheader), w); gtk_widget_show_all(page); return page; } static void end_print(GtkPrintOperation *operation, GtkPrintContext *context, gpointer user_data) { DocInfo *dinfo = user_data; if (dinfo == NULL) return; gtk_widget_hide(main_widgets.progressbar); g_object_unref(dinfo->sci); g_object_unref(dinfo->layout); g_array_free(dinfo->pages, TRUE); } static void setup_range(DocInfo *dinfo, GtkPrintContext *ctx) { dinfo->fr.hdc = dinfo->fr.hdcTarget = gtk_print_context_get_cairo_context(ctx); dinfo->fr.rcPage.left = 0; dinfo->fr.rcPage.top = 0; dinfo->fr.rcPage.right = gtk_print_context_get_width(ctx); dinfo->fr.rcPage.bottom = gtk_print_context_get_height(ctx); dinfo->fr.rc.left = dinfo->fr.rcPage.left; dinfo->fr.rc.top = dinfo->fr.rcPage.top; dinfo->fr.rc.right = dinfo->fr.rcPage.right; dinfo->fr.rc.bottom = dinfo->fr.rcPage.bottom; if (printing_prefs.print_page_header) dinfo->fr.rc.top += dinfo->line_height * 3; /* header height */ if (printing_prefs.print_page_numbers) dinfo->fr.rc.bottom -= dinfo->line_height * 1; /* footer height */ dinfo->fr.rcPage.left /= dinfo->sci_scale; dinfo->fr.rcPage.top /= dinfo->sci_scale; dinfo->fr.rcPage.right /= dinfo->sci_scale; dinfo->fr.rcPage.bottom /= dinfo->sci_scale; dinfo->fr.rc.left /= dinfo->sci_scale; dinfo->fr.rc.top /= dinfo->sci_scale; dinfo->fr.rc.right /= dinfo->sci_scale; dinfo->fr.rc.bottom /= dinfo->sci_scale; dinfo->fr.chrg.cpMin = 0; dinfo->fr.chrg.cpMax = sci_get_length(dinfo->sci); } static void begin_print(GtkPrintOperation *operation, GtkPrintContext *context, gpointer user_data) { DocInfo *dinfo = user_data; PangoContext *pango_ctx, *widget_pango_ctx; PangoFontDescription *desc; gdouble pango_res, widget_res; if (dinfo == NULL) return; gtk_widget_show(main_widgets.progressbar); /* init dinfo fields */ /* setup printing scintilla object */ dinfo->sci = editor_create_widget(dinfo->doc->editor); /* since we won't add the widget to any container, assume it's ownership */ g_object_ref_sink(dinfo->sci); SSM(dinfo->sci, SCI_SETDOCPOINTER, 0, SSM(dinfo->doc->editor->sci, SCI_GETDOCPOINTER, 0, 0)); highlighting_set_styles(dinfo->sci, dinfo->doc->file_type); sci_set_line_numbers(dinfo->sci, printing_prefs.print_line_numbers); SSM(dinfo->sci, SCI_SETVIEWWS, SCWS_INVISIBLE, 0); SSM(dinfo->sci, SCI_SETVIEWEOL, FALSE, 0); SSM(dinfo->sci, SCI_SETEDGEMODE, EDGE_NONE, 0); SSM(dinfo->sci, SCI_SETPRINTCOLOURMODE, SC_PRINT_COLOURONWHITE, 0); /* Scintilla doesn't respect the context resolution, so we'll scale ourselves. * Actually Scintilla simply doesn't know about the resolution since it creates its own * Pango context out of the Cairo target, and the resolution is in the GtkPrintOperation's * Pango context */ pango_ctx = gtk_print_context_create_pango_context(context); pango_res = pango_cairo_context_get_resolution(pango_ctx); g_object_unref(pango_ctx); widget_pango_ctx = gtk_widget_get_pango_context(GTK_WIDGET(dinfo->sci)); widget_res = pango_cairo_context_get_resolution(widget_pango_ctx); /* On Windows, for some reason the widget's resolution is -1, so follow * Pango docs and peek the font map's one. */ if (widget_res < 0) { widget_res = pango_cairo_font_map_get_resolution( (PangoCairoFontMap*) pango_context_get_font_map(widget_pango_ctx)); } dinfo->sci_scale = pango_res / widget_res; dinfo->pages = g_array_new(FALSE, FALSE, sizeof(gint)); dinfo->print_time = time(NULL); /* create a PangoLayout to be commonly used in add_page_header() and draw_page() */ desc = pango_font_description_from_string(interface_prefs.editor_font); dinfo->layout = setup_pango_layout(context, desc); pango_font_description_free(desc); get_text_dimensions(dinfo->layout, "|XMfjgq_" /* reasonably representative character set */, NULL, &dinfo->line_height); get_text_dimensions(dinfo->layout, "99999 " /* Scintilla resets the margin to the width of "99999" when printing */, &dinfo->margin_width, NULL); /* setup dinfo->fr */ setup_range(dinfo, context); } static gint format_range(DocInfo *dinfo, gboolean draw) { gint pos; cairo_save(dinfo->fr.hdc); cairo_scale(dinfo->fr.hdc, dinfo->sci_scale, dinfo->sci_scale); pos = (gint) SSM(dinfo->sci, SCI_FORMATRANGE, draw, (sptr_t) &dinfo->fr); cairo_restore(dinfo->fr.hdc); return pos; } static gboolean paginate(GtkPrintOperation *operation, GtkPrintContext *context, gpointer user_data) { DocInfo *dinfo = user_data; /* for whatever reason we get called one more time after we returned TRUE, so avoid adding * an empty page at the end */ if (dinfo->fr.chrg.cpMin >= dinfo->fr.chrg.cpMax) return TRUE; gtk_progress_bar_pulse(GTK_PROGRESS_BAR(main_widgets.progressbar)); gtk_progress_bar_set_text(GTK_PROGRESS_BAR(main_widgets.progressbar), _("Paginating")); g_array_append_val(dinfo->pages, dinfo->fr.chrg.cpMin); dinfo->fr.chrg.cpMin = format_range(dinfo, FALSE); gtk_print_operation_set_n_pages(operation, dinfo->pages->len); return dinfo->fr.chrg.cpMin >= dinfo->fr.chrg.cpMax; } static void draw_page(GtkPrintOperation *operation, GtkPrintContext *context, gint page_nr, gpointer user_data) { DocInfo *dinfo = user_data; cairo_t *cr; gdouble width, height; g_return_if_fail(dinfo != NULL); g_return_if_fail((guint)page_nr < dinfo->pages->len); if (dinfo->pages->len > 0) { gdouble fraction = (page_nr + 1) / (gdouble) dinfo->pages->len; gchar *text = g_strdup_printf(_("Page %d of %d"), page_nr + 1, dinfo->pages->len); gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(main_widgets.progressbar), fraction); gtk_progress_bar_set_text(GTK_PROGRESS_BAR(main_widgets.progressbar), text); g_free(text); } cr = gtk_print_context_get_cairo_context(context); width = gtk_print_context_get_width(context); height = gtk_print_context_get_height(context); if (printing_prefs.print_page_header) add_page_header(dinfo, cr, width, page_nr); dinfo->fr.chrg.cpMin = g_array_index(dinfo->pages, gint, page_nr); if ((guint)page_nr + 1 < dinfo->pages->len) dinfo->fr.chrg.cpMax = g_array_index(dinfo->pages, gint, page_nr + 1) - 1; else /* it's the last page, print 'til the end */ dinfo->fr.chrg.cpMax = sci_get_length(dinfo->sci); format_range(dinfo, TRUE); /* reset color */ cairo_set_source_rgb(cr, 0, 0, 0); if (printing_prefs.print_line_numbers) { /* print a thin line between the line number margin and the data */ gdouble y1 = dinfo->fr.rc.top * dinfo->sci_scale; gdouble y2 = dinfo->fr.rc.bottom * dinfo->sci_scale; gdouble x = dinfo->fr.rc.left * dinfo->sci_scale + dinfo->margin_width; if (printing_prefs.print_page_header) y1 -= 2 - 0.3; /* to connect the line number line to the page header frame, * 2 is the border, and 0.3 the line width */ cairo_set_line_width(cr, 0.3); cairo_move_to(cr, x, y1); cairo_line_to(cr, x, y2); cairo_stroke(cr); } if (printing_prefs.print_page_numbers) { gchar *line = g_strdup_printf("- %d -", page_nr + 1); pango_layout_set_markup(dinfo->layout, line, -1); pango_layout_set_alignment(dinfo->layout, PANGO_ALIGN_CENTER); cairo_move_to(cr, 0, height - dinfo->line_height); pango_cairo_show_layout(cr, dinfo->layout); g_free(line); } } static void status_changed(GtkPrintOperation *op, gpointer data) { gchar *filename = (data != NULL) ? data : GEANY_STRING_UNTITLED; if (gtk_print_operation_get_status(op) == GTK_PRINT_STATUS_FINISHED_ABORTED) msgwin_status_add(_("Did not send document %s to the printing subsystem."), filename); else if (gtk_print_operation_get_status(op) == GTK_PRINT_STATUS_FINISHED) msgwin_status_add(_("Document %s was sent to the printing subsystem."), filename); } static void printing_print_gtk(GeanyDocument *doc) { GtkPrintOperation *op; GtkPrintOperationResult res = GTK_PRINT_OPERATION_RESULT_ERROR; GError *error = NULL; static const DocInfo dinfo0; DocInfo dinfo = dinfo0; PrintWidgets *widgets; /** TODO check for monospace font, detect the widest character in the font and * use it at font_width */ widgets = g_new0(PrintWidgets, 1); /* all other fields are initialised in begin_print() */ dinfo.doc = doc; op = gtk_print_operation_new(); gtk_print_operation_set_unit(op, GTK_UNIT_POINTS); gtk_print_operation_set_show_progress(op, TRUE); gtk_print_operation_set_embed_page_setup(op, TRUE); g_signal_connect(op, "begin-print", G_CALLBACK(begin_print), &dinfo); g_signal_connect(op, "end-print", G_CALLBACK(end_print), &dinfo); g_signal_connect(op, "paginate", G_CALLBACK(paginate), &dinfo); g_signal_connect(op, "draw-page", G_CALLBACK(draw_page), &dinfo); g_signal_connect(op, "status-changed", G_CALLBACK(status_changed), doc->file_name); g_signal_connect(op, "create-custom-widget", G_CALLBACK(create_custom_widget), widgets); g_signal_connect(op, "custom-widget-apply", G_CALLBACK(custom_widget_apply), widgets); if (settings != NULL) gtk_print_operation_set_print_settings(op, settings); if (page_setup != NULL) gtk_print_operation_set_default_page_setup(op, page_setup); res = gtk_print_operation_run( op, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG, GTK_WINDOW(main_widgets.window), &error); if (res == GTK_PRINT_OPERATION_RESULT_APPLY) { if (settings != NULL) g_object_unref(settings); settings = g_object_ref(gtk_print_operation_get_print_settings(op)); /* status message is printed in the status-changed handler */ } else if (res == GTK_PRINT_OPERATION_RESULT_ERROR) { dialogs_show_msgbox(GTK_MESSAGE_ERROR, _("Printing of %s failed (%s)."), doc->file_name, error->message); g_error_free(error); } g_object_unref(op); g_free(widgets); } void printing_page_setup_gtk(void) { GtkPageSetup *new_page_setup; if (settings == NULL) settings = gtk_print_settings_new(); new_page_setup = gtk_print_run_page_setup_dialog( GTK_WINDOW(main_widgets.window), page_setup, settings); if (page_setup != NULL) g_object_unref(page_setup); page_setup = new_page_setup; } /* simple file print using an external tool */ static void print_external(GeanyDocument *doc) { gchar *cmdline; if (doc->file_name == NULL) return; if (EMPTY(printing_prefs.external_print_cmd)) { dialogs_show_msgbox(GTK_MESSAGE_ERROR, _("Please set a print command in the preferences dialog first.")); return; } cmdline = g_strdup(printing_prefs.external_print_cmd); utils_str_replace_all(&cmdline, "%f", doc->file_name); if (dialogs_show_question( _("The file \"%s\" will be printed with the following command:\n\n%s"), doc->file_name, cmdline)) { GError *error = NULL; /* /bin/sh -c emulates the system() call and makes complex commands possible * but only on non-win32 systems due to the lack of win32's shell capabilities */ #ifdef G_OS_UNIX gchar *argv[] = { "/bin/sh", "-c", cmdline, NULL }; if (!spawn_async(NULL, NULL, argv, NULL, NULL, &error)) #else if (!spawn_async(NULL, cmdline, NULL, NULL, NULL, &error)) #endif { dialogs_show_msgbox(GTK_MESSAGE_ERROR, _("Cannot execute print command \"%s\": %s. " "Check the path setting in Preferences."), printing_prefs.external_print_cmd, error->message); g_error_free(error); } else { msgwin_status_add(_("File %s printed."), doc->file_name); } } g_free(cmdline); } void printing_print_doc(GeanyDocument *doc) { g_return_if_fail(DOC_VALID(doc)); if (printing_prefs.use_gtk_printing) printing_print_gtk(doc); else print_external(doc); } geany-2.0/src/highlightingmappings.h0000644000175000017500000020236014514252267014556 00000000000000/* * highlightingmappings.h - this file is part of Geany, a fast and lightweight IDE * * Copyright 2005 The Geany contributors * * This program 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; either version 2 of the License, or * (at your option) any later version. * * This program 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef GEANY_HIGHLIGHTING_MAPPINGS_H #define GEANY_HIGHLIGHTING_MAPPINGS_H 1 #include "Scintilla.h" #include "SciLexer.h" #include G_BEGIN_DECLS /* contains all filtypes informations in the form of: * - highlighting_lexer_LANG: the SCI lexer * - highlighting_styles_LANG: SCI style/named style mappings. The first * item is also used for the default style. * - highlighting_keywords_LANG: keywords ID/name mappings * - highlighting_properties_LANG: default SCI properties and their value * where LANG is the lang part from GEANY_FILETYPE_LANG * * Using this scheme makes possible to automate style setup by simply listing LANG * and let [init_]styleset_case() macros (in highlighting.c) prepare the correct * calls. */ typedef struct { guint style; /* SCI style */ const gchar *name; /* style name in the filetypes.* file */ gboolean fill_eol; /* whether to set EOLFILLED flag to this style */ } HLStyle; typedef struct { guint id; /* SCI keyword ID */ const gchar *key; /* keywords entry name in the filetypes.* file */ gboolean merge; /* whether to merge with session types */ } HLKeyword; typedef struct { const gchar *property; const gchar *value; } HLProperty; #define EMPTY_KEYWORDS ((HLKeyword *) NULL) #define EMPTY_PROPERTIES ((HLProperty *) NULL) /* like G_N_ELEMENTS() but supports @array being NULL (for empty entries) */ #define HL_N_ENTRIES(array) ((array != NULL) ? G_N_ELEMENTS(array) : 0) /* Abaqus */ #define highlighting_lexer_ABAQUS SCLEX_ABAQUS static const HLStyle highlighting_styles_ABAQUS[] = { { SCE_ABAQUS_DEFAULT, "default", FALSE }, { SCE_ABAQUS_COMMENT, "comment", FALSE }, { SCE_ABAQUS_NUMBER, "number", FALSE }, { SCE_ABAQUS_STRING, "string", FALSE }, { SCE_ABAQUS_OPERATOR, "operator", FALSE }, { SCE_ABAQUS_PROCESSOR, "processor", FALSE }, { SCE_ABAQUS_STARCOMMAND, "starcommand", FALSE }, { SCE_ABAQUS_ARGUMENT, "argument", FALSE } }; static const HLKeyword highlighting_keywords_ABAQUS[] = { { 0, "processors", FALSE }, { 1, "commands", FALSE }, { 2, "slashommands", FALSE }, { 3, "starcommands", FALSE }, { 4, "arguments", FALSE }, { 5, "functions", FALSE } }; #define highlighting_properties_ABAQUS EMPTY_PROPERTIES /* Ada */ #define highlighting_lexer_ADA SCLEX_ADA static const HLStyle highlighting_styles_ADA[] = { { SCE_ADA_DEFAULT, "default", FALSE }, { SCE_ADA_WORD, "word", FALSE }, { SCE_ADA_IDENTIFIER, "identifier", FALSE }, { SCE_ADA_NUMBER, "number", FALSE }, { SCE_ADA_DELIMITER, "delimiter", FALSE }, { SCE_ADA_CHARACTER, "character", FALSE }, { SCE_ADA_CHARACTEREOL, "charactereol", FALSE }, { SCE_ADA_STRING, "string", FALSE }, { SCE_ADA_STRINGEOL, "stringeol", FALSE }, { SCE_ADA_LABEL, "label", FALSE }, { SCE_ADA_COMMENTLINE, "commentline", FALSE }, { SCE_ADA_ILLEGAL, "illegal", FALSE } }; static const HLKeyword highlighting_keywords_ADA[] = { { 0, "primary", FALSE } }; #define highlighting_properties_ADA EMPTY_PROPERTIES /* ActionScript */ #define highlighting_lexer_AS SCLEX_CPP #define highlighting_styles_AS highlighting_styles_C static const HLKeyword highlighting_keywords_AS[] = { { 0, "primary", FALSE }, { 1, "secondary", FALSE }, { 3, "classes", FALSE } }; #define highlighting_properties_AS highlighting_properties_C /* Asccidoc */ #define highlighting_lexer_ASCIIDOC SCLEX_ASCIIDOC static const HLStyle highlighting_styles_ASCIIDOC[] = { { SCE_ASCIIDOC_DEFAULT, "default", FALSE }, { SCE_ASCIIDOC_STRONG1, "strong", FALSE }, { SCE_ASCIIDOC_STRONG2, "strong", FALSE }, { SCE_ASCIIDOC_EM1, "emphasis", FALSE }, { SCE_ASCIIDOC_EM2, "emphasis", FALSE }, { SCE_ASCIIDOC_HEADER1, "header1", FALSE }, { SCE_ASCIIDOC_HEADER2, "header2", FALSE }, { SCE_ASCIIDOC_HEADER3, "header3", FALSE }, { SCE_ASCIIDOC_HEADER4, "header4", FALSE }, { SCE_ASCIIDOC_HEADER5, "header5", FALSE }, { SCE_ASCIIDOC_HEADER6, "header6", FALSE }, { SCE_ASCIIDOC_ULIST_ITEM, "ulist_item", FALSE }, { SCE_ASCIIDOC_OLIST_ITEM, "olist_item", FALSE }, { SCE_ASCIIDOC_BLOCKQUOTE, "blockquote", FALSE }, { SCE_ASCIIDOC_LINK, "link", FALSE }, { SCE_ASCIIDOC_CODEBK, "code", FALSE }, { SCE_ASCIIDOC_PASSBK, "passthrough", FALSE }, { SCE_ASCIIDOC_COMMENT, "comment", FALSE }, { SCE_ASCIIDOC_COMMENTBK, "comment", FALSE }, { SCE_ASCIIDOC_LITERAL, "literal", FALSE }, { SCE_ASCIIDOC_LITERALBK, "literal", FALSE }, { SCE_ASCIIDOC_ATTRIB, "attrib", FALSE }, { SCE_ASCIIDOC_ATTRIBVAL, "attribval", FALSE }, { SCE_ASCIIDOC_MACRO, "macro", FALSE } }; #define highlighting_keywords_ASCIIDOC EMPTY_KEYWORDS #define highlighting_properties_ASCIIDOC EMPTY_PROPERTIES /* ASM */ #define highlighting_lexer_ASM SCLEX_ASM static const HLStyle highlighting_styles_ASM[] = { { SCE_ASM_DEFAULT, "default", FALSE }, { SCE_ASM_COMMENT, "comment", FALSE }, { SCE_ASM_NUMBER, "number", FALSE }, { SCE_ASM_STRING, "string", FALSE }, { SCE_ASM_OPERATOR, "operator", FALSE }, { SCE_ASM_IDENTIFIER, "identifier", FALSE }, { SCE_ASM_CPUINSTRUCTION, "cpuinstruction", FALSE }, { SCE_ASM_MATHINSTRUCTION, "mathinstruction", FALSE }, { SCE_ASM_REGISTER, "register", FALSE }, { SCE_ASM_DIRECTIVE, "directive", FALSE }, { SCE_ASM_DIRECTIVEOPERAND, "directiveoperand", FALSE }, { SCE_ASM_COMMENTBLOCK, "commentblock", FALSE }, { SCE_ASM_CHARACTER, "character", FALSE }, { SCE_ASM_STRINGEOL, "stringeol", FALSE }, { SCE_ASM_EXTINSTRUCTION, "extinstruction", FALSE }, { SCE_ASM_COMMENTDIRECTIVE, "commentdirective", FALSE } }; static const HLKeyword highlighting_keywords_ASM[] = { { 0, "instructions", FALSE }, /*{ 1, "instructions", FALSE },*/ { 2, "registers", FALSE }, { 3, "directives", FALSE } /*{ 5, "instructions", FALSE }*/ }; #define highlighting_properties_ASM EMPTY_PROPERTIES /* BASIC */ #define highlighting_lexer_BASIC SCLEX_FREEBASIC static const HLStyle highlighting_styles_BASIC[] = { { SCE_B_DEFAULT, "default", FALSE }, { SCE_B_COMMENT, "comment", FALSE }, { SCE_B_COMMENTBLOCK, "commentblock", FALSE }, { SCE_B_DOCLINE, "docline", FALSE }, { SCE_B_DOCBLOCK, "docblock", FALSE }, { SCE_B_DOCKEYWORD, "dockeyword", FALSE }, { SCE_B_NUMBER, "number", FALSE }, { SCE_B_KEYWORD, "word", FALSE }, { SCE_B_STRING, "string", FALSE }, { SCE_B_PREPROCESSOR, "preprocessor", FALSE }, { SCE_B_OPERATOR, "operator", FALSE }, { SCE_B_IDENTIFIER, "identifier", FALSE }, { SCE_B_DATE, "date", FALSE }, { SCE_B_STRINGEOL, "stringeol", FALSE }, { SCE_B_KEYWORD2, "word2", FALSE }, { SCE_B_KEYWORD3, "word3", FALSE }, { SCE_B_KEYWORD4, "word4", FALSE }, { SCE_B_CONSTANT, "constant", FALSE }, { SCE_B_ASM, "asm", FALSE }, { SCE_B_LABEL, "label", FALSE }, { SCE_B_ERROR, "error", FALSE }, { SCE_B_HEXNUMBER, "hexnumber", FALSE }, { SCE_B_BINNUMBER, "binnumber", FALSE } }; static const HLKeyword highlighting_keywords_BASIC[] = { { 0, "keywords", FALSE }, { 1, "preprocessor", FALSE }, { 2, "user1", FALSE }, { 3, "user2", FALSE } }; #define highlighting_properties_BASIC EMPTY_PROPERTIES /* BATCH */ #define highlighting_lexer_BATCH SCLEX_BATCH static const HLStyle highlighting_styles_BATCH[] = { { SCE_BAT_DEFAULT, "default", FALSE }, { SCE_BAT_COMMENT, "comment", FALSE }, { SCE_BAT_LABEL, "label", FALSE }, { SCE_BAT_WORD, "word", FALSE }, { SCE_BAT_HIDE, "hide", FALSE }, { SCE_BAT_COMMAND, "command", FALSE }, { SCE_BAT_IDENTIFIER, "identifier", FALSE }, { SCE_BAT_OPERATOR, "operator", FALSE } }; static const HLKeyword highlighting_keywords_BATCH[] = { { 0, "keywords", FALSE }, { 1, "keywords_optional", FALSE } }; #define highlighting_properties_BATCH EMPTY_PROPERTIES /* C */ /* Also used by some other SCLEX_CPP-based filetypes */ #define highlighting_lexer_C SCLEX_CPP static const HLStyle highlighting_styles_C[] = { { SCE_C_DEFAULT, "default", FALSE }, { SCE_C_COMMENT, "comment", FALSE }, { SCE_C_COMMENTLINE, "commentline", FALSE }, { SCE_C_COMMENTDOC, "commentdoc", FALSE }, { SCE_C_PREPROCESSORCOMMENT, "preprocessorcomment", FALSE }, { SCE_C_PREPROCESSORCOMMENTDOC, "preprocessorcommentdoc", FALSE }, { SCE_C_NUMBER, "number", FALSE }, { SCE_C_WORD, "word", FALSE }, { SCE_C_WORD2, "word2", FALSE }, { SCE_C_STRING, "string", FALSE }, { SCE_C_STRINGRAW, "stringraw", FALSE }, { SCE_C_CHARACTER, "character", FALSE }, { SCE_C_USERLITERAL, "userliteral", FALSE }, { SCE_C_UUID, "uuid", FALSE }, { SCE_C_PREPROCESSOR, "preprocessor", FALSE }, { SCE_C_OPERATOR, "operator", FALSE }, { SCE_C_IDENTIFIER, "identifier", FALSE }, { SCE_C_STRINGEOL, "stringeol", FALSE }, { SCE_C_VERBATIM, "verbatim", FALSE }, /* triple verbatims use the same style */ { SCE_C_TRIPLEVERBATIM, "verbatim", FALSE }, { SCE_C_REGEX, "regex", FALSE }, { SCE_C_HASHQUOTEDSTRING, "hashquotedstring", FALSE }, { SCE_C_COMMENTLINEDOC, "commentlinedoc", FALSE }, { SCE_C_COMMENTDOCKEYWORD, "commentdockeyword", FALSE }, { SCE_C_COMMENTDOCKEYWORDERROR, "commentdockeyworderror", FALSE }, /* used for local structs and typedefs */ { SCE_C_GLOBALCLASS, "globalclass", FALSE }, { SCE_C_TASKMARKER, "taskmarker", FALSE }, { SCE_C_ESCAPESEQUENCE, "escapesequence", FALSE } }; static const HLKeyword highlighting_keywords_C[] = { { 0, "primary", FALSE }, /* SCI_SETKEYWORDS = 1 - secondary + global tags file types, see below */ { 1, "secondary", TRUE }, { 2, "docComment", FALSE } /* SCI_SETKEYWORDS = 3 is for current session types - see document_highlight_tags() */ }; static const HLProperty highlighting_properties_C[] = { { "fold.cpp.comment.explicit", "0" } }; /* Caml */ #define highlighting_lexer_CAML SCLEX_CAML static const HLStyle highlighting_styles_CAML[] = { { SCE_CAML_DEFAULT, "default", FALSE }, { SCE_CAML_COMMENT, "comment", FALSE }, { SCE_CAML_COMMENT1, "comment1", FALSE }, { SCE_CAML_COMMENT2, "comment2", FALSE }, { SCE_CAML_COMMENT3, "comment3", FALSE }, { SCE_CAML_NUMBER, "number", FALSE }, { SCE_CAML_KEYWORD, "keyword", FALSE }, { SCE_CAML_KEYWORD2, "keyword2", FALSE }, { SCE_CAML_KEYWORD3, "keyword3", FALSE }, { SCE_CAML_STRING, "string", FALSE }, { SCE_CAML_CHAR, "char", FALSE }, { SCE_CAML_OPERATOR, "operator", FALSE }, { SCE_CAML_IDENTIFIER, "identifier", FALSE }, { SCE_CAML_TAGNAME, "tagname", FALSE }, { SCE_CAML_LINENUM, "linenum", FALSE }, { SCE_CAML_WHITE, "white", FALSE } }; static const HLKeyword highlighting_keywords_CAML[] = { { 0, "keywords", FALSE }, { 1, "keywords_optional", FALSE } }; #define highlighting_properties_CAML EMPTY_PROPERTIES /* CMake */ #define highlighting_lexer_CMAKE SCLEX_CMAKE static const HLStyle highlighting_styles_CMAKE[] = { { SCE_CMAKE_DEFAULT, "default", FALSE }, { SCE_CMAKE_COMMENT, "comment", FALSE }, { SCE_CMAKE_STRINGDQ, "stringdq", FALSE }, { SCE_CMAKE_STRINGLQ, "stringlq", FALSE }, { SCE_CMAKE_STRINGRQ, "stringrq", FALSE }, { SCE_CMAKE_COMMANDS, "command", FALSE }, { SCE_CMAKE_PARAMETERS, "parameters", FALSE }, { SCE_CMAKE_VARIABLE, "variable", FALSE }, { SCE_CMAKE_USERDEFINED, "userdefined", FALSE }, { SCE_CMAKE_WHILEDEF, "whiledef", FALSE }, { SCE_CMAKE_FOREACHDEF, "foreachdef", FALSE }, { SCE_CMAKE_IFDEFINEDEF, "ifdefinedef", FALSE }, { SCE_CMAKE_MACRODEF, "macrodef", FALSE }, { SCE_CMAKE_STRINGVAR, "stringvar", FALSE }, { SCE_CMAKE_NUMBER, "number", FALSE } }; static const HLKeyword highlighting_keywords_CMAKE[] = { { 0, "commands", FALSE }, { 1, "parameters", FALSE }, { 2, "userdefined", FALSE } }; #define highlighting_properties_CMAKE EMPTY_PROPERTIES /* CoffeeScript */ #define highlighting_lexer_COFFEESCRIPT SCLEX_COFFEESCRIPT static const HLStyle highlighting_styles_COFFEESCRIPT[] = { { SCE_COFFEESCRIPT_DEFAULT, "default", FALSE }, { SCE_COFFEESCRIPT_COMMENTLINE, "commentline", FALSE }, { SCE_COFFEESCRIPT_NUMBER, "number", FALSE }, { SCE_COFFEESCRIPT_WORD, "word", FALSE }, { SCE_COFFEESCRIPT_STRING, "string", FALSE }, { SCE_COFFEESCRIPT_CHARACTER, "character", FALSE }, { SCE_COFFEESCRIPT_OPERATOR, "operator", FALSE }, { SCE_COFFEESCRIPT_IDENTIFIER, "identifier", FALSE }, { SCE_COFFEESCRIPT_STRINGEOL, "stringeol", FALSE }, { SCE_COFFEESCRIPT_REGEX, "regex", FALSE }, { SCE_COFFEESCRIPT_WORD2, "word2", FALSE }, { SCE_COFFEESCRIPT_GLOBALCLASS, "globalclass", FALSE }, { SCE_COFFEESCRIPT_COMMENTBLOCK, "commentblock", FALSE }, { SCE_COFFEESCRIPT_VERBOSE_REGEX, "verbose_regex", FALSE }, { SCE_COFFEESCRIPT_VERBOSE_REGEX_COMMENT, "verbose_regex_comment",FALSE }, { SCE_COFFEESCRIPT_INSTANCEPROPERTY, "instanceproperty", FALSE } }; static const HLKeyword highlighting_keywords_COFFEESCRIPT[] = { { 0, "primary", FALSE }, { 1, "secondary", FALSE }, { 3, "globalclass", FALSE } }; #define highlighting_properties_COFFEESCRIPT EMPTY_PROPERTIES /* CSS */ #define highlighting_lexer_CSS SCLEX_CSS static const HLStyle highlighting_styles_CSS[] = { { SCE_CSS_DEFAULT, "default", FALSE }, { SCE_CSS_COMMENT, "comment", FALSE }, { SCE_CSS_TAG, "tag", FALSE }, { SCE_CSS_CLASS, "class", FALSE }, { SCE_CSS_PSEUDOCLASS, "pseudoclass", FALSE }, { SCE_CSS_UNKNOWN_PSEUDOCLASS, "unknown_pseudoclass", FALSE }, { SCE_CSS_UNKNOWN_IDENTIFIER, "unknown_identifier", FALSE }, { SCE_CSS_OPERATOR, "operator", FALSE }, { SCE_CSS_IDENTIFIER, "identifier", FALSE }, { SCE_CSS_DOUBLESTRING, "doublestring", FALSE }, { SCE_CSS_SINGLESTRING, "singlestring", FALSE }, { SCE_CSS_ATTRIBUTE, "attribute", FALSE }, { SCE_CSS_VALUE, "value", FALSE }, { SCE_CSS_ID, "id", FALSE }, { SCE_CSS_IDENTIFIER2, "identifier2", FALSE }, { SCE_CSS_VARIABLE, "variable", FALSE }, { SCE_CSS_IMPORTANT, "important", FALSE }, { SCE_CSS_DIRECTIVE, "directive", FALSE }, { SCE_CSS_IDENTIFIER3, "identifier3", FALSE }, { SCE_CSS_PSEUDOELEMENT, "pseudoelement", FALSE }, { SCE_CSS_EXTENDED_IDENTIFIER, "extended_identifier", FALSE }, { SCE_CSS_EXTENDED_PSEUDOCLASS, "extended_pseudoclass", FALSE }, { SCE_CSS_EXTENDED_PSEUDOELEMENT, "extended_pseudoelement", FALSE }, { SCE_CSS_GROUP_RULE, "group_rule", FALSE } }; static const HLKeyword highlighting_keywords_CSS[] = { { 0, "primary", FALSE }, { 1, "pseudoclasses", FALSE }, { 2, "secondary", FALSE }, { 3, "css3_properties", FALSE }, { 4, "pseudo_elements", FALSE }, { 5, "browser_css_properties", FALSE }, { 6, "browser_pseudo_classes", FALSE }, { 7, "browser_pseudo_elements", FALSE } }; #define highlighting_properties_CSS EMPTY_PROPERTIES /* Cobol */ #define highlighting_lexer_COBOL SCLEX_COBOL #define highlighting_styles_COBOL highlighting_styles_C static const HLKeyword highlighting_keywords_COBOL[] = { { 0, "primary", FALSE }, { 1, "secondary", FALSE }, { 2, "extended_keywords", FALSE } }; #define highlighting_properties_COBOL highlighting_properties_C /* Conf */ #define highlighting_lexer_CONF SCLEX_PROPERTIES static const HLStyle highlighting_styles_CONF[] = { { SCE_PROPS_DEFAULT, "default", FALSE }, { SCE_PROPS_COMMENT, "comment", FALSE }, { SCE_PROPS_SECTION, "section", FALSE }, { SCE_PROPS_KEY, "key", FALSE }, { SCE_PROPS_ASSIGNMENT, "assignment", FALSE }, { SCE_PROPS_DEFVAL, "defval", FALSE } }; #define highlighting_keywords_CONF EMPTY_KEYWORDS #define highlighting_properties_CONF EMPTY_PROPERTIES /* D */ #define highlighting_lexer_D SCLEX_D static const HLStyle highlighting_styles_D[] = { { SCE_D_DEFAULT, "default", FALSE }, { SCE_D_COMMENT, "comment", FALSE }, { SCE_D_COMMENTLINE, "commentline", FALSE }, { SCE_D_COMMENTDOC, "commentdoc", FALSE }, { SCE_D_COMMENTNESTED, "commentnested", FALSE }, { SCE_D_NUMBER, "number", FALSE }, { SCE_D_WORD, "word", FALSE }, { SCE_D_WORD2, "word2", FALSE }, { SCE_D_WORD3, "word3", FALSE }, { SCE_D_TYPEDEF, "typedef", FALSE }, /* FIXME: don't remap here */ { SCE_D_WORD5, "typedef", FALSE }, { SCE_D_STRING, "string", FALSE }, { SCE_D_STRINGB, "string", FALSE }, { SCE_D_STRINGR, "string", FALSE }, { SCE_D_STRINGEOL, "stringeol", FALSE }, { SCE_D_CHARACTER, "character", FALSE }, { SCE_D_OPERATOR, "operator", FALSE }, { SCE_D_IDENTIFIER, "identifier", FALSE }, { SCE_D_COMMENTLINEDOC, "commentlinedoc", FALSE }, { SCE_D_COMMENTDOCKEYWORD, "commentdockeyword", FALSE }, { SCE_D_COMMENTDOCKEYWORDERROR, "commentdockeyworderror", FALSE } /* these are for user-defined keywords we don't set yet */ /*{ SCE_D_WORD6, "word6", FALSE }, { SCE_D_WORD7, "word7", FALSE }*/ }; static const HLKeyword highlighting_keywords_D[] = { { 0, "primary", FALSE }, /* SCI_SETKEYWORDS = 1 - secondary + global tags file types */ { 1, "secondary", TRUE }, { 2, "docComment", FALSE }, /* SCI_SETKEYWORDS = 3 is for current session types - see document_highlight_tags() */ { 4, "types", FALSE }, }; #define highlighting_properties_D EMPTY_PROPERTIES /* Diff */ #define highlighting_lexer_DIFF SCLEX_DIFF static const HLStyle highlighting_styles_DIFF[] = { { SCE_DIFF_DEFAULT, "default", FALSE }, { SCE_DIFF_COMMENT, "comment", FALSE }, { SCE_DIFF_COMMAND, "command", FALSE }, { SCE_DIFF_HEADER, "header", FALSE }, { SCE_DIFF_POSITION, "position", FALSE }, { SCE_DIFF_DELETED, "deleted", FALSE }, { SCE_DIFF_ADDED, "added", FALSE }, { SCE_DIFF_CHANGED, "changed", FALSE }, { SCE_DIFF_PATCH_ADD, "patch_add", FALSE }, { SCE_DIFF_PATCH_DELETE, "patch_delete", FALSE }, { SCE_DIFF_REMOVED_PATCH_ADD, "removed_patch_add", FALSE }, { SCE_DIFF_REMOVED_PATCH_DELETE, "removed_patch_delete", FALSE } }; #define highlighting_keywords_DIFF EMPTY_KEYWORDS #define highlighting_properties_DIFF EMPTY_PROPERTIES #define highlighting_lexer_DOCBOOK SCLEX_XML static const HLStyle highlighting_styles_DOCBOOK[] = { { SCE_H_DEFAULT, "default", FALSE }, { SCE_H_TAG, "tag", FALSE }, { SCE_H_TAGUNKNOWN, "tagunknown", FALSE }, { SCE_H_ATTRIBUTE, "attribute", FALSE }, { SCE_H_ATTRIBUTEUNKNOWN, "attributeunknown", FALSE }, { SCE_H_NUMBER, "number", FALSE }, { SCE_H_DOUBLESTRING, "doublestring", FALSE }, { SCE_H_SINGLESTRING, "singlestring", FALSE }, { SCE_H_OTHER, "other", FALSE }, { SCE_H_COMMENT, "comment", FALSE }, { SCE_H_ENTITY, "entity", FALSE }, { SCE_H_TAGEND, "tagend", FALSE }, { SCE_H_XMLSTART, "xmlstart", TRUE }, { SCE_H_XMLEND, "xmlend", FALSE }, { SCE_H_CDATA, "cdata", FALSE }, { SCE_H_QUESTION, "question", FALSE }, { SCE_H_VALUE, "value", FALSE }, { SCE_H_XCCOMMENT, "xccomment", FALSE }, { SCE_H_SGML_DEFAULT, "sgml_default", FALSE }, { SCE_H_SGML_COMMENT, "sgml_comment", FALSE }, { SCE_H_SGML_SPECIAL, "sgml_special", FALSE }, { SCE_H_SGML_COMMAND, "sgml_command", FALSE }, { SCE_H_SGML_DOUBLESTRING, "sgml_doublestring", FALSE }, { SCE_H_SGML_SIMPLESTRING, "sgml_simplestring", FALSE }, { SCE_H_SGML_1ST_PARAM, "sgml_1st_param", FALSE }, { SCE_H_SGML_ENTITY, "sgml_entity", FALSE }, { SCE_H_SGML_BLOCK_DEFAULT, "sgml_block_default", FALSE }, { SCE_H_SGML_1ST_PARAM_COMMENT, "sgml_1st_param_comment", FALSE }, { SCE_H_SGML_ERROR, "sgml_error", FALSE } }; static const HLKeyword highlighting_keywords_DOCBOOK[] = { { 0, "elements", FALSE }, { 5, "dtd", FALSE } }; #define highlighting_properties_DOCBOOK EMPTY_PROPERTIES /* Erlang */ #define highlighting_lexer_ERLANG SCLEX_ERLANG static const HLStyle highlighting_styles_ERLANG[] = { { SCE_ERLANG_DEFAULT, "default", FALSE }, { SCE_ERLANG_COMMENT, "comment", FALSE }, { SCE_ERLANG_VARIABLE, "variable", FALSE }, { SCE_ERLANG_NUMBER, "number", FALSE }, { SCE_ERLANG_KEYWORD, "keyword", FALSE }, { SCE_ERLANG_STRING, "string", FALSE }, { SCE_ERLANG_OPERATOR, "operator", FALSE }, { SCE_ERLANG_ATOM, "atom", FALSE }, { SCE_ERLANG_FUNCTION_NAME, "function_name", FALSE }, { SCE_ERLANG_CHARACTER, "character", FALSE }, { SCE_ERLANG_MACRO, "macro", FALSE }, { SCE_ERLANG_RECORD, "record", FALSE }, { SCE_ERLANG_PREPROC, "preproc", FALSE }, { SCE_ERLANG_NODE_NAME, "node_name", FALSE }, { SCE_ERLANG_COMMENT_FUNCTION, "comment_function", FALSE }, { SCE_ERLANG_COMMENT_MODULE, "comment_module", FALSE }, { SCE_ERLANG_COMMENT_DOC, "comment_doc", FALSE }, { SCE_ERLANG_COMMENT_DOC_MACRO, "comment_doc_macro", FALSE }, { SCE_ERLANG_ATOM_QUOTED, "atom_quoted", FALSE }, { SCE_ERLANG_MACRO_QUOTED, "macro_quoted", FALSE }, { SCE_ERLANG_RECORD_QUOTED, "record_quoted", FALSE }, { SCE_ERLANG_NODE_NAME_QUOTED, "node_name_quoted", FALSE }, { SCE_ERLANG_BIFS, "bifs", FALSE }, { SCE_ERLANG_MODULES, "modules", FALSE }, { SCE_ERLANG_MODULES_ATT, "modules_att", FALSE }, { SCE_ERLANG_UNKNOWN, "unknown", FALSE } }; static const HLKeyword highlighting_keywords_ERLANG[] = { { 0, "keywords", FALSE }, { 1, "bifs", FALSE }, { 2, "preproc", FALSE }, { 3, "module", FALSE }, { 4, "doc", FALSE }, { 5, "doc_macro", FALSE } }; #define highlighting_properties_ERLANG EMPTY_PROPERTIES /* F77 */ #define highlighting_lexer_F77 SCLEX_F77 static const HLStyle highlighting_styles_F77[] = { { SCE_F_DEFAULT, "default", FALSE }, { SCE_F_COMMENT, "comment", FALSE }, { SCE_F_NUMBER, "number", FALSE }, { SCE_F_STRING1, "string", FALSE }, { SCE_F_OPERATOR, "operator", FALSE }, { SCE_F_IDENTIFIER, "identifier", FALSE }, { SCE_F_STRING2, "string2", FALSE }, { SCE_F_WORD, "word", FALSE }, { SCE_F_WORD2, "word2", FALSE }, { SCE_F_WORD3, "word3", FALSE }, { SCE_F_PREPROCESSOR, "preprocessor", FALSE }, { SCE_F_OPERATOR2, "operator2", FALSE }, { SCE_F_CONTINUATION, "continuation", FALSE }, { SCE_F_STRINGEOL, "stringeol", FALSE }, { SCE_F_LABEL, "label", FALSE } }; static const HLKeyword highlighting_keywords_F77[] = { { 0, "primary", FALSE }, { 1, "intrinsic_functions", FALSE }, { 2, "user_functions", FALSE } }; #define highlighting_properties_F77 EMPTY_PROPERTIES /* Forth */ #define highlighting_lexer_FORTH SCLEX_FORTH static const HLStyle highlighting_styles_FORTH[] = { { SCE_FORTH_DEFAULT, "default", FALSE }, { SCE_FORTH_COMMENT, "comment", FALSE }, { SCE_FORTH_COMMENT_ML, "commentml", FALSE }, { SCE_FORTH_IDENTIFIER, "identifier", FALSE }, { SCE_FORTH_CONTROL, "control", FALSE }, { SCE_FORTH_KEYWORD, "keyword", FALSE }, { SCE_FORTH_DEFWORD, "defword", FALSE }, { SCE_FORTH_PREWORD1, "preword1", FALSE }, { SCE_FORTH_PREWORD2, "preword2", FALSE }, { SCE_FORTH_NUMBER, "number", FALSE }, { SCE_FORTH_STRING, "string", FALSE }, { SCE_FORTH_LOCALE, "locale", FALSE } }; static const HLKeyword highlighting_keywords_FORTH[] = { { 0, "primary", FALSE }, { 1, "keyword", FALSE }, { 2, "defword", FALSE }, { 3, "preword1", FALSE }, { 4, "preword2", FALSE }, { 5, "string", FALSE } }; #define highlighting_properties_FORTH EMPTY_PROPERTIES /* Fortran */ /* F77 and Fortran (F9x) uses different lexers but shares styles and keywords */ #define highlighting_lexer_FORTRAN SCLEX_FORTRAN #define highlighting_styles_FORTRAN highlighting_styles_F77 #define highlighting_keywords_FORTRAN highlighting_keywords_F77 #define highlighting_properties_FORTRAN highlighting_properties_F77 /* GDScript */ #define highlighting_lexer_GDSCRIPT SCLEX_GDSCRIPT static const HLStyle highlighting_styles_GDSCRIPT[] = { { SCE_GD_DEFAULT, "default", FALSE }, { SCE_GD_COMMENTLINE, "commentline", FALSE }, { SCE_GD_NUMBER, "number", FALSE }, { SCE_GD_STRING, "string", FALSE }, { SCE_GD_CHARACTER, "character", FALSE }, { SCE_GD_WORD, "word", FALSE }, { SCE_GD_TRIPLE, "triple", FALSE }, { SCE_GD_TRIPLEDOUBLE, "tripledouble", FALSE }, { SCE_GD_CLASSNAME, "classname", FALSE }, { SCE_GD_FUNCNAME, "funcname", FALSE }, { SCE_GD_OPERATOR, "operator", FALSE }, { SCE_GD_IDENTIFIER, "identifier", FALSE }, { SCE_GD_COMMENTBLOCK, "commentblock", FALSE }, { SCE_GD_STRINGEOL, "stringeol", FALSE }, { SCE_GD_WORD2, "word2", FALSE }, { SCE_GD_ANNOTATION, "annotation", FALSE }, { SCE_GD_NODEPATH, "notepath", FALSE } }; static const HLKeyword highlighting_keywords_GDSCRIPT[] = { { 0, "primary", FALSE }, { 1, "identifiers", FALSE } }; #define highlighting_properties_GDSCRIPT EMPTY_PROPERTIES /* Go */ #define highlighting_lexer_GO SCLEX_CPP #define highlighting_styles_GO highlighting_styles_C #define highlighting_keywords_GO highlighting_keywords_C #define highlighting_properties_GO highlighting_properties_C /* Haskell */ #define highlighting_lexer_HASKELL SCLEX_HASKELL static const HLStyle highlighting_styles_HASKELL[] = { { SCE_HA_DEFAULT, "default", FALSE }, { SCE_HA_COMMENTLINE, "commentline", FALSE }, { SCE_HA_COMMENTBLOCK, "commentblock", FALSE }, { SCE_HA_COMMENTBLOCK2, "commentblock2", FALSE }, { SCE_HA_COMMENTBLOCK3, "commentblock3", FALSE }, { SCE_HA_NUMBER, "number", FALSE }, { SCE_HA_KEYWORD, "keyword", FALSE }, { SCE_HA_IMPORT, "import", FALSE }, { SCE_HA_STRING, "string", FALSE }, { SCE_HA_CHARACTER, "character", FALSE }, { SCE_HA_CLASS, "class", FALSE }, { SCE_HA_OPERATOR, "operator", FALSE }, { SCE_HA_IDENTIFIER, "identifier", FALSE }, { SCE_HA_INSTANCE, "instance", FALSE }, { SCE_HA_CAPITAL, "capital", FALSE }, { SCE_HA_MODULE, "module", FALSE }, { SCE_HA_DATA, "data", FALSE }, { SCE_HA_PRAGMA, "pragma", FALSE }, { SCE_HA_PREPROCESSOR, "preprocessor", FALSE }, { SCE_HA_STRINGEOL, "stringeol", FALSE }, { SCE_HA_RESERVED_OPERATOR, "reserved_operator", FALSE }, { SCE_HA_LITERATE_COMMENT, "literate_comment", FALSE }, { SCE_HA_LITERATE_CODEDELIM, "literate_codedelim", FALSE } }; static const HLKeyword highlighting_keywords_HASKELL[] = { { 0, "keywords", FALSE }, { 1, "ffi", FALSE }, { 2, "reserved_operators", FALSE } }; #define highlighting_properties_HASKELL EMPTY_PROPERTIES /* HAXE */ #define highlighting_lexer_HAXE SCLEX_CPP #define highlighting_styles_HAXE highlighting_styles_C static const HLKeyword highlighting_keywords_HAXE[] = { { 0, "primary", FALSE }, { 1, "secondary", FALSE }, { 3, "classes", FALSE } }; #define highlighting_properties_HAXE highlighting_properties_C /* HTML */ #define highlighting_lexer_HTML SCLEX_HTML static const HLStyle highlighting_styles_HTML[] = { { SCE_H_DEFAULT, "html_default", FALSE }, { SCE_H_TAG, "html_tag", FALSE }, { SCE_H_TAGUNKNOWN, "html_tagunknown", FALSE }, { SCE_H_ATTRIBUTE, "html_attribute", FALSE }, { SCE_H_ATTRIBUTEUNKNOWN, "html_attributeunknown", FALSE }, { SCE_H_NUMBER, "html_number", FALSE }, { SCE_H_DOUBLESTRING, "html_doublestring", FALSE }, { SCE_H_SINGLESTRING, "html_singlestring", FALSE }, { SCE_H_OTHER, "html_other", FALSE }, { SCE_H_COMMENT, "html_comment", FALSE }, { SCE_H_ENTITY, "html_entity", FALSE }, { SCE_H_TAGEND, "html_tagend", FALSE }, { SCE_H_XMLSTART, "html_xmlstart", TRUE }, { SCE_H_XMLEND, "html_xmlend", FALSE }, { SCE_H_SCRIPT, "html_script", FALSE }, { SCE_H_ASP, "html_asp", TRUE }, { SCE_H_ASPAT, "html_aspat", TRUE }, { SCE_H_CDATA, "html_cdata", FALSE }, { SCE_H_QUESTION, "html_question", FALSE }, { SCE_H_VALUE, "html_value", FALSE }, { SCE_H_XCCOMMENT, "html_xccomment", FALSE }, { SCE_H_SGML_DEFAULT, "sgml_default", FALSE }, { SCE_H_SGML_COMMENT, "sgml_comment", FALSE }, { SCE_H_SGML_SPECIAL, "sgml_special", FALSE }, { SCE_H_SGML_COMMAND, "sgml_command", FALSE }, { SCE_H_SGML_DOUBLESTRING, "sgml_doublestring", FALSE }, { SCE_H_SGML_SIMPLESTRING, "sgml_simplestring", FALSE }, { SCE_H_SGML_1ST_PARAM, "sgml_1st_param", FALSE }, { SCE_H_SGML_ENTITY, "sgml_entity", FALSE }, { SCE_H_SGML_BLOCK_DEFAULT, "sgml_block_default", FALSE }, { SCE_H_SGML_1ST_PARAM_COMMENT, "sgml_1st_param_comment", FALSE }, { SCE_H_SGML_ERROR, "sgml_error", FALSE }, /* embedded JavaScript */ { SCE_HJ_START, "jscript_start", FALSE }, { SCE_HJ_DEFAULT, "jscript_default", FALSE }, { SCE_HJ_COMMENT, "jscript_comment", FALSE }, { SCE_HJ_COMMENTLINE, "jscript_commentline", FALSE }, { SCE_HJ_COMMENTDOC, "jscript_commentdoc", FALSE }, { SCE_HJ_NUMBER, "jscript_number", FALSE }, { SCE_HJ_WORD, "jscript_word", FALSE }, { SCE_HJ_KEYWORD, "jscript_keyword", FALSE }, { SCE_HJ_DOUBLESTRING, "jscript_doublestring", FALSE }, { SCE_HJ_SINGLESTRING, "jscript_singlestring", FALSE }, { SCE_HJ_SYMBOLS, "jscript_symbols", FALSE }, { SCE_HJ_STRINGEOL, "jscript_stringeol", FALSE }, { SCE_HJ_REGEX, "jscript_regex", FALSE }, /* for HB, VBScript?, use the same styles as for JavaScript */ { SCE_HB_START, "jscript_start", FALSE }, { SCE_HB_DEFAULT, "jscript_default", FALSE }, { SCE_HB_COMMENTLINE, "jscript_commentline", FALSE }, { SCE_HB_NUMBER, "jscript_number", FALSE }, { SCE_HB_WORD, "jscript_keyword", FALSE }, /* keywords */ { SCE_HB_STRING, "jscript_doublestring", FALSE }, { SCE_HB_IDENTIFIER, "jscript_symbols", FALSE }, { SCE_HB_STRINGEOL, "jscript_stringeol", FALSE }, /* for HBA, VBScript?, use the same styles as for JavaScript */ { SCE_HBA_START, "jscript_start", FALSE }, { SCE_HBA_DEFAULT, "jscript_default", FALSE }, { SCE_HBA_COMMENTLINE, "jscript_commentline", FALSE }, { SCE_HBA_NUMBER, "jscript_number", FALSE }, { SCE_HBA_WORD, "jscript_keyword", FALSE }, /* keywords */ { SCE_HBA_STRING, "jscript_doublestring", FALSE }, { SCE_HBA_IDENTIFIER, "jscript_symbols", FALSE }, { SCE_HBA_STRINGEOL, "jscript_stringeol", FALSE }, /* for HJA, ASP Javascript, use the same styles as for JavaScript */ { SCE_HJA_START, "jscript_start", FALSE }, { SCE_HJA_DEFAULT, "jscript_default", FALSE }, { SCE_HJA_COMMENT, "jscript_comment", FALSE }, { SCE_HJA_COMMENTLINE, "jscript_commentline", FALSE }, { SCE_HJA_COMMENTDOC, "jscript_commentdoc", FALSE }, { SCE_HJA_NUMBER, "jscript_number", FALSE }, { SCE_HJA_WORD, "jscript_word", FALSE }, { SCE_HJA_KEYWORD, "jscript_keyword", FALSE }, { SCE_HJA_DOUBLESTRING, "jscript_doublestring", FALSE }, { SCE_HJA_SINGLESTRING, "jscript_singlestring", FALSE }, { SCE_HJA_SYMBOLS, "jscript_symbols", FALSE }, { SCE_HJA_STRINGEOL, "jscript_stringeol", FALSE }, { SCE_HJA_REGEX, "jscript_regex", FALSE }, /* embedded Python */ { SCE_HP_START, "jscript_start", FALSE }, { SCE_HP_DEFAULT, "python_default", FALSE }, { SCE_HP_COMMENTLINE, "python_commentline", FALSE }, { SCE_HP_NUMBER, "python_number", FALSE }, { SCE_HP_STRING, "python_string", FALSE }, { SCE_HP_CHARACTER, "python_character", FALSE }, { SCE_HP_WORD, "python_word", FALSE }, { SCE_HP_TRIPLE, "python_triple", FALSE }, { SCE_HP_TRIPLEDOUBLE, "python_tripledouble", FALSE }, { SCE_HP_CLASSNAME, "python_classname", FALSE }, { SCE_HP_DEFNAME, "python_defname", FALSE }, { SCE_HP_OPERATOR, "python_operator", FALSE }, { SCE_HP_IDENTIFIER, "python_identifier", FALSE }, /* for embedded HPA (what is this?) we use the Python styles */ { SCE_HPA_START, "jscript_start", FALSE }, { SCE_HPA_DEFAULT, "python_default", FALSE }, { SCE_HPA_COMMENTLINE, "python_commentline", FALSE }, { SCE_HPA_NUMBER, "python_number", FALSE }, { SCE_HPA_STRING, "python_string", FALSE }, { SCE_HPA_CHARACTER, "python_character", FALSE }, { SCE_HPA_WORD, "python_word", FALSE }, { SCE_HPA_TRIPLE, "python_triple", FALSE }, { SCE_HPA_TRIPLEDOUBLE, "python_tripledouble", FALSE }, { SCE_HPA_CLASSNAME, "python_classname", FALSE }, { SCE_HPA_DEFNAME, "python_defname", FALSE }, { SCE_HPA_OPERATOR, "python_operator", FALSE }, { SCE_HPA_IDENTIFIER, "python_identifier", FALSE }, /* PHP */ { SCE_HPHP_DEFAULT, "php_default", FALSE }, { SCE_HPHP_SIMPLESTRING, "php_simplestring", FALSE }, { SCE_HPHP_HSTRING, "php_hstring", FALSE }, { SCE_HPHP_NUMBER, "php_number", FALSE }, { SCE_HPHP_WORD, "php_word", FALSE }, { SCE_HPHP_VARIABLE, "php_variable", FALSE }, { SCE_HPHP_COMMENT, "php_comment", FALSE }, { SCE_HPHP_COMMENTLINE, "php_commentline", FALSE }, { SCE_HPHP_OPERATOR, "php_operator", FALSE }, { SCE_HPHP_HSTRING_VARIABLE, "php_hstring_variable", FALSE }, { SCE_HPHP_COMPLEX_VARIABLE, "php_complex_variable", FALSE } }; static const HLKeyword highlighting_keywords_HTML[] = { { 0, "html", FALSE }, { 1, "javascript", FALSE }, { 2, "vbscript", FALSE }, { 3, "python", FALSE }, { 4, "php", FALSE }, { 5, "sgml", FALSE } }; static const HLProperty highlighting_properties_HTML[] = { { "fold.html", "1" }, { "fold.html.preprocessor", "0" } }; /* Java */ #define highlighting_lexer_JAVA SCLEX_CPP #define highlighting_styles_JAVA highlighting_styles_C static const HLKeyword highlighting_keywords_JAVA[] = { { 0, "primary", FALSE }, /* SCI_SETKEYWORDS = 1 - secondary + global tags file types, see below */ { 1, "secondary", TRUE }, { 2, "doccomment", FALSE }, /* SCI_SETKEYWORDS = 3 is for current session types - see document_highlight_tags() */ { 4, "typedefs", FALSE } }; #define highlighting_properties_JAVA highlighting_properties_C /* JavaScript */ #define highlighting_lexer_JS SCLEX_CPP #define highlighting_styles_JS highlighting_styles_C static const HLKeyword highlighting_keywords_JS[] = { { 0, "primary", FALSE }, { 1, "secondary", FALSE } }; #define highlighting_properties_JS highlighting_properties_C /* Julia */ #define highlighting_lexer_JULIA SCLEX_JULIA static const HLStyle highlighting_styles_JULIA[] = { { SCE_JULIA_DEFAULT, "default", FALSE }, { SCE_JULIA_COMMENT, "comment", FALSE }, { SCE_JULIA_NUMBER, "number", FALSE }, { SCE_JULIA_KEYWORD1, "keyword1", FALSE }, { SCE_JULIA_KEYWORD2, "keyword2", FALSE }, { SCE_JULIA_KEYWORD3, "keyword3", FALSE }, { SCE_JULIA_CHAR, "char", FALSE }, { SCE_JULIA_OPERATOR, "operator", FALSE }, { SCE_JULIA_BRACKET, "bracket", FALSE }, { SCE_JULIA_IDENTIFIER, "identifier", FALSE }, { SCE_JULIA_STRING, "string", FALSE }, { SCE_JULIA_SYMBOL, "symbol", FALSE }, { SCE_JULIA_MACRO, "macro", FALSE }, { SCE_JULIA_STRINGINTERP, "stringinterp", FALSE }, { SCE_JULIA_DOCSTRING, "docstring", FALSE }, { SCE_JULIA_STRINGLITERAL, "stringliteral", FALSE }, { SCE_JULIA_COMMAND, "command", FALSE }, { SCE_JULIA_COMMANDLITERAL, "commandliteral", FALSE }, { SCE_JULIA_TYPEANNOT, "typeannotation", FALSE }, { SCE_JULIA_LEXERROR, "lexerror", FALSE }, { SCE_JULIA_KEYWORD4, "keyword4", FALSE }, { SCE_JULIA_TYPEOPERATOR, "typeoperator", FALSE }, }; static const HLKeyword highlighting_keywords_JULIA[] = { { 0, "primary", FALSE }, { 1, "secondary", FALSE }, { 2, "tertiary", FALSE }, { 3, "functions", FALSE } }; #define highlighting_properties_JULIA EMPTY_PROPERTIES /* LaTeX */ #define highlighting_lexer_LATEX SCLEX_LATEX static const HLStyle highlighting_styles_LATEX[] = { { SCE_L_DEFAULT, "default", FALSE }, { SCE_L_COMMAND, "command", FALSE }, { SCE_L_TAG, "tag", FALSE }, { SCE_L_MATH, "math", FALSE }, { SCE_L_COMMENT, "comment", FALSE }, { SCE_L_TAG2, "tag2", FALSE }, { SCE_L_MATH2, "math2", FALSE }, { SCE_L_COMMENT2, "comment2", FALSE }, { SCE_L_VERBATIM, "verbatim", FALSE }, { SCE_L_SHORTCMD, "shortcmd", FALSE }, { SCE_L_SPECIAL, "special", FALSE }, { SCE_L_CMDOPT, "cmdopt", FALSE }, { SCE_L_ERROR, "error", FALSE } }; static const HLKeyword highlighting_keywords_LATEX[] = { { 0, "primary", FALSE } }; #define highlighting_properties_LATEX EMPTY_PROPERTIES /* Lisp */ #define highlighting_lexer_LISP SCLEX_LISP static const HLStyle highlighting_styles_LISP[] = { { SCE_LISP_DEFAULT, "default", FALSE }, { SCE_LISP_COMMENT, "comment", FALSE }, { SCE_LISP_MULTI_COMMENT, "multicomment", FALSE }, { SCE_LISP_NUMBER, "number", FALSE }, { SCE_LISP_KEYWORD, "keyword", FALSE }, { SCE_LISP_SYMBOL, "symbol", FALSE }, { SCE_LISP_STRING, "string", FALSE }, { SCE_LISP_STRINGEOL, "stringeol", FALSE }, { SCE_LISP_IDENTIFIER, "identifier", FALSE }, { SCE_LISP_OPERATOR, "operator", FALSE }, { SCE_LISP_SPECIAL, "special", FALSE }, { SCE_LISP_KEYWORD_KW, "keywordkw", FALSE } }; static const HLKeyword highlighting_keywords_LISP[] = { { 0, "keywords", FALSE }, { 1, "special_keywords", FALSE } }; #define highlighting_properties_LISP EMPTY_PROPERTIES /* Lua */ #define highlighting_lexer_LUA SCLEX_LUA static const HLStyle highlighting_styles_LUA[] = { { SCE_LUA_DEFAULT, "default", FALSE }, { SCE_LUA_COMMENT, "comment", FALSE }, { SCE_LUA_COMMENTLINE, "commentline", FALSE }, { SCE_LUA_COMMENTDOC, "commentdoc", FALSE }, { SCE_LUA_NUMBER, "number", FALSE }, { SCE_LUA_WORD, "word", FALSE }, { SCE_LUA_STRING, "string", FALSE }, { SCE_LUA_CHARACTER, "character", FALSE }, { SCE_LUA_LITERALSTRING, "literalstring", FALSE }, { SCE_LUA_PREPROCESSOR, "preprocessor", FALSE }, { SCE_LUA_OPERATOR, "operator", FALSE }, { SCE_LUA_IDENTIFIER, "identifier", FALSE }, { SCE_LUA_STRINGEOL, "stringeol", FALSE }, { SCE_LUA_WORD2, "function_basic", FALSE }, { SCE_LUA_WORD3, "function_other", FALSE }, { SCE_LUA_WORD4, "coroutines", FALSE }, { SCE_LUA_WORD5, "word5", FALSE }, { SCE_LUA_WORD6, "word6", FALSE }, { SCE_LUA_WORD7, "word7", FALSE }, { SCE_LUA_WORD8, "word8", FALSE }, { SCE_LUA_LABEL, "label", FALSE } }; static const HLKeyword highlighting_keywords_LUA[] = { { 0, "keywords", FALSE }, { 1, "function_basic", FALSE }, { 2, "function_other", FALSE }, { 3, "coroutines", FALSE }, { 4, "user1", FALSE }, { 5, "user2", FALSE }, { 6, "user3", FALSE }, { 7, "user4", FALSE } }; #define highlighting_properties_LUA EMPTY_PROPERTIES /* Makefile */ #define highlighting_lexer_MAKE SCLEX_MAKEFILE static const HLStyle highlighting_styles_MAKE[] = { { SCE_MAKE_DEFAULT, "default", FALSE }, { SCE_MAKE_COMMENT, "comment", FALSE }, { SCE_MAKE_PREPROCESSOR, "preprocessor", FALSE }, { SCE_MAKE_IDENTIFIER, "identifier", FALSE }, { SCE_MAKE_OPERATOR, "operator", FALSE }, { SCE_MAKE_TARGET, "target", FALSE }, { SCE_MAKE_IDEOL, "ideol", FALSE } }; #define highlighting_keywords_MAKE EMPTY_KEYWORDS #define highlighting_properties_MAKE EMPTY_PROPERTIES /* Markdown */ #define highlighting_lexer_MARKDOWN SCLEX_MARKDOWN static const HLStyle highlighting_styles_MARKDOWN[] = { { SCE_MARKDOWN_DEFAULT, "default", FALSE }, { SCE_MARKDOWN_LINE_BEGIN, "default", FALSE }, /* FIXME: avoid in-code re-mappings */ { SCE_MARKDOWN_PRECHAR, "default", FALSE }, { SCE_MARKDOWN_STRONG1, "strong", FALSE }, { SCE_MARKDOWN_STRONG2, "strong", FALSE }, { SCE_MARKDOWN_EM1, "emphasis", FALSE }, { SCE_MARKDOWN_EM2, "emphasis", FALSE }, { SCE_MARKDOWN_HEADER1, "header1", FALSE }, { SCE_MARKDOWN_HEADER2, "header2", FALSE }, { SCE_MARKDOWN_HEADER3, "header3", FALSE }, { SCE_MARKDOWN_HEADER4, "header4", FALSE }, { SCE_MARKDOWN_HEADER5, "header5", FALSE }, { SCE_MARKDOWN_HEADER6, "header6", FALSE }, { SCE_MARKDOWN_ULIST_ITEM, "ulist_item", FALSE }, { SCE_MARKDOWN_OLIST_ITEM, "olist_item", FALSE }, { SCE_MARKDOWN_BLOCKQUOTE, "blockquote", FALSE }, { SCE_MARKDOWN_STRIKEOUT, "strikeout", FALSE }, { SCE_MARKDOWN_HRULE, "hrule", FALSE }, { SCE_MARKDOWN_LINK, "link", FALSE }, { SCE_MARKDOWN_CODE, "code", FALSE }, { SCE_MARKDOWN_CODE2, "code", FALSE }, { SCE_MARKDOWN_CODEBK, "codebk", FALSE } }; #define highlighting_keywords_MARKDOWN EMPTY_KEYWORDS #define highlighting_properties_MARKDOWN EMPTY_PROPERTIES /* Matlab */ #define highlighting_lexer_MATLAB SCLEX_OCTAVE /* not MATLAB to support Octave's # comments */ static const HLStyle highlighting_styles_MATLAB[] = { { SCE_MATLAB_DEFAULT, "default", FALSE }, { SCE_MATLAB_COMMENT, "comment", FALSE }, { SCE_MATLAB_COMMAND, "command", FALSE }, { SCE_MATLAB_NUMBER, "number", FALSE }, { SCE_MATLAB_KEYWORD, "keyword", FALSE }, { SCE_MATLAB_STRING, "string", FALSE }, { SCE_MATLAB_OPERATOR, "operator", FALSE }, { SCE_MATLAB_IDENTIFIER, "identifier", FALSE }, { SCE_MATLAB_DOUBLEQUOTESTRING, "doublequotedstring", FALSE } }; static const HLKeyword highlighting_keywords_MATLAB[] = { { 0, "primary", FALSE } }; #define highlighting_properties_MATLAB EMPTY_PROPERTIES /* NSIS */ #define highlighting_lexer_NSIS SCLEX_NSIS static const HLStyle highlighting_styles_NSIS[] = { { SCE_NSIS_DEFAULT, "default", FALSE }, { SCE_NSIS_COMMENT, "comment", FALSE }, { SCE_NSIS_STRINGDQ, "stringdq", FALSE }, { SCE_NSIS_STRINGLQ, "stringlq", FALSE }, { SCE_NSIS_STRINGRQ, "stringrq", FALSE }, { SCE_NSIS_FUNCTION, "function", FALSE }, { SCE_NSIS_VARIABLE, "variable", FALSE }, { SCE_NSIS_LABEL, "label", FALSE }, { SCE_NSIS_USERDEFINED, "userdefined", FALSE }, { SCE_NSIS_SECTIONDEF, "sectiondef", FALSE }, { SCE_NSIS_SUBSECTIONDEF, "subsectiondef", FALSE }, { SCE_NSIS_IFDEFINEDEF, "ifdefinedef", FALSE }, { SCE_NSIS_MACRODEF, "macrodef", FALSE }, { SCE_NSIS_STRINGVAR, "stringvar", FALSE }, { SCE_NSIS_NUMBER, "number", FALSE }, { SCE_NSIS_SECTIONGROUP, "sectiongroup", FALSE }, { SCE_NSIS_PAGEEX, "pageex", FALSE }, { SCE_NSIS_FUNCTIONDEF, "functiondef", FALSE }, { SCE_NSIS_COMMENTBOX, "commentbox", FALSE } }; static const HLKeyword highlighting_keywords_NSIS[] = { { 0, "functions", FALSE }, { 1, "variables", FALSE }, { 2, "lables", FALSE }, { 3, "userdefined", FALSE } }; #define highlighting_properties_NSIS EMPTY_PROPERTIES /* Objective-C */ #define highlighting_lexer_OBJECTIVEC highlighting_lexer_C #define highlighting_styles_OBJECTIVEC highlighting_styles_C static const HLKeyword highlighting_keywords_OBJECTIVEC[] = { { 0, "primary", FALSE }, /* SCI_SETKEYWORDS = 1 - secondary + global tags file types, see below */ { 1, "secondary", TRUE }, { 2, "docComment", FALSE } /* SCI_SETKEYWORDS = 3 is for current session types - see document_highlight_tags() */ }; #define highlighting_properties_OBJECTIVEC highlighting_properties_C /* Pascal */ #define highlighting_lexer_PASCAL SCLEX_PASCAL static const HLStyle highlighting_styles_PASCAL[] = { { SCE_PAS_DEFAULT, "default", FALSE }, { SCE_PAS_IDENTIFIER, "identifier", FALSE }, { SCE_PAS_COMMENT, "comment", FALSE }, { SCE_PAS_COMMENT2, "comment2", FALSE }, { SCE_PAS_COMMENTLINE, "commentline", FALSE }, { SCE_PAS_PREPROCESSOR, "preprocessor", FALSE }, { SCE_PAS_PREPROCESSOR2, "preprocessor2", FALSE }, { SCE_PAS_NUMBER, "number", FALSE }, { SCE_PAS_HEXNUMBER, "hexnumber", FALSE }, { SCE_PAS_WORD, "word", FALSE }, { SCE_PAS_STRING, "string", FALSE }, { SCE_PAS_STRINGEOL, "stringeol", FALSE }, { SCE_PAS_CHARACTER, "character", FALSE }, { SCE_PAS_OPERATOR, "operator", FALSE }, { SCE_PAS_ASM, "asm", FALSE } }; static const HLKeyword highlighting_keywords_PASCAL[] = { { 0, "primary", FALSE } }; #define highlighting_properties_PASCAL EMPTY_PROPERTIES /* Perl */ #define highlighting_lexer_PERL SCLEX_PERL static const HLStyle highlighting_styles_PERL[] = { { SCE_PL_DEFAULT, "default", FALSE }, { SCE_PL_ERROR, "error", FALSE }, { SCE_PL_COMMENTLINE, "commentline", FALSE }, { SCE_PL_NUMBER, "number", FALSE }, { SCE_PL_WORD, "word", FALSE }, { SCE_PL_STRING, "string", FALSE }, { SCE_PL_CHARACTER, "character", FALSE }, { SCE_PL_PREPROCESSOR, "preprocessor", FALSE }, { SCE_PL_OPERATOR, "operator", FALSE }, { SCE_PL_IDENTIFIER, "identifier", FALSE }, { SCE_PL_SCALAR, "scalar", FALSE }, { SCE_PL_POD, "pod", FALSE }, { SCE_PL_REGEX, "regex", FALSE }, { SCE_PL_ARRAY, "array", FALSE }, { SCE_PL_HASH, "hash", FALSE }, { SCE_PL_SYMBOLTABLE, "symboltable", FALSE }, { SCE_PL_BACKTICKS, "backticks", FALSE }, { SCE_PL_POD_VERB, "pod_verbatim", FALSE }, { SCE_PL_REGSUBST, "reg_subst", FALSE }, { SCE_PL_DATASECTION, "datasection", FALSE }, { SCE_PL_HERE_DELIM, "here_delim", FALSE }, { SCE_PL_HERE_Q, "here_q", FALSE }, { SCE_PL_HERE_QQ, "here_qq", FALSE }, { SCE_PL_HERE_QX, "here_qx", FALSE }, { SCE_PL_STRING_Q, "string_q", FALSE }, { SCE_PL_STRING_QQ, "string_qq", FALSE }, { SCE_PL_STRING_QX, "string_qx", FALSE }, { SCE_PL_STRING_QR, "string_qr", FALSE }, { SCE_PL_STRING_QW, "string_qw", FALSE }, { SCE_PL_VARIABLE_INDEXER, "variable_indexer", FALSE }, { SCE_PL_PUNCTUATION, "punctuation", FALSE }, { SCE_PL_LONGQUOTE, "longquote", FALSE }, { SCE_PL_SUB_PROTOTYPE, "sub_prototype", FALSE }, { SCE_PL_FORMAT_IDENT, "format_ident", FALSE }, { SCE_PL_FORMAT, "format", FALSE }, { SCE_PL_STRING_VAR, "string_var", FALSE }, { SCE_PL_XLAT, "xlat", FALSE }, { SCE_PL_REGEX_VAR, "regex_var", FALSE }, { SCE_PL_REGSUBST_VAR, "regsubst_var", FALSE }, { SCE_PL_BACKTICKS_VAR, "backticks_var", FALSE }, { SCE_PL_HERE_QQ_VAR, "here_qq_var", FALSE }, { SCE_PL_HERE_QX_VAR, "here_qx_var", FALSE }, { SCE_PL_STRING_QQ_VAR, "string_qq_var", FALSE }, { SCE_PL_STRING_QX_VAR, "string_qx_var", FALSE }, { SCE_PL_STRING_QR_VAR, "string_qr_var", FALSE } }; static const HLKeyword highlighting_keywords_PERL[] = { { 0, "primary", FALSE } }; #define highlighting_properties_PERL EMPTY_PROPERTIES /* PHP */ #define highlighting_lexer_PHP SCLEX_HTML #define highlighting_styles_PHP highlighting_styles_HTML #define highlighting_keywords_PHP highlighting_keywords_HTML #define highlighting_properties_PHP highlighting_properties_HTML /* PO (gettext) */ #define highlighting_lexer_PO SCLEX_PO static const HLStyle highlighting_styles_PO[] = { { SCE_PO_DEFAULT, "default", FALSE }, { SCE_PO_COMMENT, "comment", FALSE }, { SCE_PO_PROGRAMMER_COMMENT, "programmer_comment", FALSE }, { SCE_PO_REFERENCE, "reference", FALSE }, { SCE_PO_FLAGS, "flags", FALSE }, { SCE_PO_FUZZY, "fuzzy", FALSE }, { SCE_PO_MSGID, "msgid", FALSE }, { SCE_PO_MSGID_TEXT, "msgid_text", FALSE }, { SCE_PO_MSGID_TEXT_EOL, "msgid_text_eol", FALSE }, { SCE_PO_MSGSTR, "msgstr", FALSE }, { SCE_PO_MSGSTR_TEXT, "msgstr_text", FALSE }, { SCE_PO_MSGSTR_TEXT_EOL, "msgstr_text_eol", FALSE }, { SCE_PO_MSGCTXT, "msgctxt", FALSE }, { SCE_PO_MSGCTXT_TEXT, "msgctxt_text", FALSE }, { SCE_PO_MSGCTXT_TEXT_EOL, "msgctxt_text_eol", FALSE }, { SCE_PO_ERROR, "error", FALSE } }; #define highlighting_keywords_PO EMPTY_KEYWORDS #define highlighting_properties_PO EMPTY_PROPERTIES /* PowerShell */ #define highlighting_lexer_POWERSHELL SCLEX_POWERSHELL static const HLStyle highlighting_styles_POWERSHELL[] = { { SCE_POWERSHELL_DEFAULT, "default", FALSE }, { SCE_POWERSHELL_COMMENT, "comment", FALSE }, { SCE_POWERSHELL_STRING, "string", FALSE }, { SCE_POWERSHELL_CHARACTER, "character", FALSE }, { SCE_POWERSHELL_NUMBER, "number", FALSE }, { SCE_POWERSHELL_VARIABLE, "variable", FALSE }, { SCE_POWERSHELL_OPERATOR, "operator", FALSE }, { SCE_POWERSHELL_IDENTIFIER, "identifier", FALSE }, { SCE_POWERSHELL_KEYWORD, "keyword", FALSE }, { SCE_POWERSHELL_CMDLET, "cmdlet", FALSE }, { SCE_POWERSHELL_ALIAS, "alias", FALSE }, { SCE_POWERSHELL_FUNCTION, "function", FALSE }, { SCE_POWERSHELL_USER1, "user1", FALSE }, { SCE_POWERSHELL_COMMENTSTREAM, "commentstream", FALSE }, { SCE_POWERSHELL_HERE_STRING, "here_string", FALSE }, { SCE_POWERSHELL_HERE_CHARACTER, "here_character", FALSE }, { SCE_POWERSHELL_COMMENTDOCKEYWORD, "commentdockeyword", FALSE }, }; static const HLKeyword highlighting_keywords_POWERSHELL[] = { { 0, "keywords", FALSE }, { 1, "cmdlets", FALSE }, { 2, "aliases", FALSE }, { 3, "functions", FALSE }, { 4, "user1", FALSE }, { 5, "docComment", FALSE }, }; #define highlighting_properties_POWERSHELL EMPTY_PROPERTIES /* Python */ #define highlighting_lexer_PYTHON SCLEX_PYTHON static const HLStyle highlighting_styles_PYTHON[] = { { SCE_P_DEFAULT, "default", FALSE }, { SCE_P_COMMENTLINE, "commentline", FALSE }, { SCE_P_NUMBER, "number", FALSE }, { SCE_P_STRING, "string", FALSE }, { SCE_P_CHARACTER, "character", FALSE }, { SCE_P_WORD, "word", FALSE }, { SCE_P_TRIPLE, "triple", FALSE }, { SCE_P_TRIPLEDOUBLE, "tripledouble", FALSE }, { SCE_P_CLASSNAME, "classname", FALSE }, { SCE_P_DEFNAME, "defname", FALSE }, { SCE_P_OPERATOR, "operator", FALSE }, { SCE_P_IDENTIFIER, "identifier", FALSE }, { SCE_P_COMMENTBLOCK, "commentblock", FALSE }, { SCE_P_STRINGEOL, "stringeol", FALSE }, { SCE_P_WORD2, "word2", FALSE }, { SCE_P_FSTRING, "fstring", FALSE }, { SCE_P_FCHARACTER, "fcharacter", FALSE }, { SCE_P_FTRIPLE, "ftriple", FALSE }, { SCE_P_FTRIPLEDOUBLE, "ftripledouble", FALSE }, { SCE_P_DECORATOR, "decorator", FALSE }, { SCE_P_ATTRIBUTE, "attribute", FALSE } }; static const HLKeyword highlighting_keywords_PYTHON[] = { { 0, "primary", FALSE }, { 1, "identifiers", FALSE } }; #define highlighting_properties_PYTHON EMPTY_PROPERTIES /* R */ #define highlighting_lexer_R SCLEX_R static const HLStyle highlighting_styles_R[] = { { SCE_R_DEFAULT, "default", FALSE }, { SCE_R_COMMENT, "comment", FALSE }, { SCE_R_KWORD, "kword", FALSE }, { SCE_R_OPERATOR, "operator", FALSE }, { SCE_R_BASEKWORD, "basekword", FALSE }, { SCE_R_OTHERKWORD, "otherkword", FALSE }, { SCE_R_NUMBER, "number", FALSE }, { SCE_R_STRING, "string", FALSE }, { SCE_R_STRING2, "string2", FALSE }, { SCE_R_IDENTIFIER, "identifier", FALSE }, { SCE_R_INFIX, "infix", FALSE }, { SCE_R_INFIXEOL, "infixeol", FALSE }, { SCE_R_BACKTICKS, "backticks", FALSE }, { SCE_R_RAWSTRING, "stringraw", FALSE }, { SCE_R_RAWSTRING2, "stringraw", FALSE }, { SCE_R_ESCAPESEQUENCE, "escapesequence", FALSE } }; static const HLKeyword highlighting_keywords_R[] = { { 0, "primary", FALSE }, { 1, "package", FALSE }, { 2, "package_other", FALSE } }; #define highlighting_properties_R EMPTY_PROPERTIES /* Ruby */ #define highlighting_lexer_RUBY SCLEX_RUBY static const HLStyle highlighting_styles_RUBY[] = { { SCE_RB_DEFAULT, "default", FALSE }, { SCE_RB_COMMENTLINE, "commentline", FALSE }, { SCE_RB_NUMBER, "number", FALSE }, { SCE_RB_STRING, "string", FALSE }, { SCE_RB_CHARACTER, "character", FALSE }, { SCE_RB_WORD, "word", FALSE }, { SCE_RB_GLOBAL, "global", FALSE }, { SCE_RB_SYMBOL, "symbol", FALSE }, { SCE_RB_CLASSNAME, "classname", FALSE }, { SCE_RB_DEFNAME, "defname", FALSE }, { SCE_RB_OPERATOR, "operator", FALSE }, { SCE_RB_IDENTIFIER, "identifier", FALSE }, { SCE_RB_MODULE_NAME, "modulename", FALSE }, { SCE_RB_BACKTICKS, "backticks", FALSE }, { SCE_RB_INSTANCE_VAR, "instancevar", FALSE }, { SCE_RB_CLASS_VAR, "classvar", FALSE }, { SCE_RB_DATASECTION, "datasection", FALSE }, { SCE_RB_HERE_DELIM, "heredelim", FALSE }, { SCE_RB_WORD_DEMOTED, "worddemoted", FALSE }, { SCE_RB_STDIN, "stdin", FALSE }, { SCE_RB_STDOUT, "stdout", FALSE }, { SCE_RB_STDERR, "stderr", FALSE }, { SCE_RB_REGEX, "regex", FALSE }, { SCE_RB_HERE_Q, "here_q", FALSE }, { SCE_RB_HERE_QQ, "here_qq", FALSE }, { SCE_RB_HERE_QX, "here_qx", FALSE }, { SCE_RB_STRING_Q, "string_q", FALSE }, { SCE_RB_STRING_QQ, "string_qq", FALSE }, { SCE_RB_STRING_QX, "string_qx", FALSE }, { SCE_RB_STRING_QR, "string_qr", FALSE }, { SCE_RB_STRING_QW, "string_qw", FALSE }, { SCE_RB_STRING_W, "string_qw", FALSE }, { SCE_RB_STRING_QI, "symbol", FALSE }, { SCE_RB_STRING_QS, "symbol", FALSE }, { SCE_RB_STRING_I, "symbol", FALSE }, { SCE_RB_UPPER_BOUND, "upper_bound", FALSE }, { SCE_RB_ERROR, "error", FALSE }, { SCE_RB_POD, "pod", FALSE } }; static const HLKeyword highlighting_keywords_RUBY[] = { { 0, "primary", FALSE } }; #define highlighting_properties_RUBY EMPTY_PROPERTIES /* Rust */ #define highlighting_lexer_RUST SCLEX_RUST static const HLStyle highlighting_styles_RUST[] = { { SCE_RUST_DEFAULT, "default", FALSE }, { SCE_RUST_COMMENTBLOCK, "commentblock", FALSE }, { SCE_RUST_COMMENTLINE, "commentline", FALSE }, { SCE_RUST_COMMENTBLOCKDOC, "commentblockdoc", FALSE }, { SCE_RUST_COMMENTLINEDOC, "commentlinedoc", FALSE }, { SCE_RUST_NUMBER, "number", FALSE }, { SCE_RUST_WORD, "word", FALSE }, { SCE_RUST_WORD2, "word2", FALSE }, { SCE_RUST_WORD3, "word3", FALSE }, { SCE_RUST_WORD4, "word4", FALSE }, { SCE_RUST_WORD5, "word5", FALSE }, { SCE_RUST_WORD6, "word6", FALSE }, { SCE_RUST_WORD7, "word7", FALSE }, { SCE_RUST_STRING, "string", FALSE }, { SCE_RUST_STRINGR, "stringraw", FALSE }, { SCE_RUST_CHARACTER, "character", FALSE }, { SCE_RUST_OPERATOR, "operator", FALSE }, { SCE_RUST_IDENTIFIER, "identifier", FALSE }, { SCE_RUST_LIFETIME, "lifetime", FALSE }, { SCE_RUST_MACRO, "macro", FALSE }, { SCE_RUST_LEXERROR, "lexerror", FALSE }, { SCE_RUST_BYTESTRING, "bytestring", FALSE }, { SCE_RUST_BYTESTRINGR, "bytestringr", FALSE }, { SCE_RUST_BYTECHARACTER, "bytecharacter", FALSE } }; static const HLKeyword highlighting_keywords_RUST[] = { { 0, "primary", FALSE }, /* SCI_SETKEYWORDS = 1 - secondary + global tags file types */ { 1, "secondary", TRUE }, { 2, "tertiary", FALSE }, /* SCI_SETKEYWORDS = 3 is for current session types - see document_highlight_tags() */ }; #define highlighting_properties_RUST EMPTY_PROPERTIES /* SH */ #define highlighting_lexer_SH SCLEX_BASH static const HLStyle highlighting_styles_SH[] = { { SCE_SH_DEFAULT, "default", FALSE }, { SCE_SH_COMMENTLINE, "commentline", FALSE }, { SCE_SH_NUMBER, "number", FALSE }, { SCE_SH_WORD, "word", FALSE }, { SCE_SH_STRING, "string", FALSE }, { SCE_SH_CHARACTER, "character", FALSE }, { SCE_SH_OPERATOR, "operator", FALSE }, { SCE_SH_IDENTIFIER, "identifier", FALSE }, { SCE_SH_BACKTICKS, "backticks", FALSE }, { SCE_SH_PARAM, "param", FALSE }, { SCE_SH_SCALAR, "scalar", FALSE }, { SCE_SH_ERROR, "error", FALSE }, { SCE_SH_HERE_DELIM, "here_delim", FALSE }, { SCE_SH_HERE_Q, "here_q", FALSE } }; static const HLKeyword highlighting_keywords_SH[] = { { 0, "primary", FALSE } }; #define highlighting_properties_SH EMPTY_PROPERTIES /* SMALLTALK */ #define highlighting_lexer_SMALLTALK SCLEX_SMALLTALK static const HLStyle highlighting_styles_SMALLTALK[] = { { SCE_ST_DEFAULT, "default", FALSE }, { SCE_ST_SPECIAL, "special", FALSE }, { SCE_ST_SYMBOL, "symbol", FALSE }, { SCE_ST_ASSIGN, "assignment", FALSE }, { SCE_ST_RETURN, "return", FALSE }, { SCE_ST_NUMBER, "number", FALSE }, { SCE_ST_BINARY, "binary", FALSE }, { SCE_ST_SPEC_SEL, "special_selector", FALSE }, { SCE_ST_KWSEND, "keyword_send", FALSE }, { SCE_ST_GLOBAL, "global", FALSE }, { SCE_ST_SELF, "self", FALSE }, { SCE_ST_SUPER, "super", FALSE }, { SCE_ST_NIL, "nil", FALSE }, { SCE_ST_BOOL, "bool", FALSE }, { SCE_ST_COMMENT, "comment", FALSE }, { SCE_ST_STRING, "string", FALSE }, { SCE_ST_CHARACTER, "character", FALSE } }; static const HLKeyword highlighting_keywords_SMALLTALK[] = { { 0, "special_selector", FALSE } }; #define highlighting_properties_SMALLTALK EMPTY_PROPERTIES /* SQL */ #define highlighting_lexer_SQL SCLEX_SQL static const HLStyle highlighting_styles_SQL[] = { { SCE_SQL_DEFAULT, "default", FALSE }, { SCE_SQL_COMMENT, "comment", FALSE }, { SCE_SQL_COMMENTLINE, "commentline", FALSE }, { SCE_SQL_COMMENTDOC, "commentdoc", FALSE }, { SCE_SQL_COMMENTLINEDOC, "commentlinedoc", FALSE }, { SCE_SQL_COMMENTDOCKEYWORD, "commentdockeyword", FALSE }, { SCE_SQL_COMMENTDOCKEYWORDERROR, "commentdockeyworderror", FALSE }, { SCE_SQL_NUMBER, "number", FALSE }, { SCE_SQL_WORD, "word", FALSE }, { SCE_SQL_WORD2, "word2", FALSE }, { SCE_SQL_STRING, "string", FALSE }, { SCE_SQL_CHARACTER, "character", FALSE }, { SCE_SQL_OPERATOR, "operator", FALSE }, { SCE_SQL_IDENTIFIER, "identifier", FALSE }, { SCE_SQL_SQLPLUS, "sqlplus", FALSE }, { SCE_SQL_SQLPLUS_PROMPT, "sqlplus_prompt", FALSE }, { SCE_SQL_SQLPLUS_COMMENT, "sqlplus_comment", FALSE }, { SCE_SQL_QUOTEDIDENTIFIER, "quotedidentifier", FALSE }, { SCE_SQL_QOPERATOR, "qoperator", FALSE } /* these are for user-defined keywords we don't set yet */ /*{ SCE_SQL_USER1, "user1", FALSE }, { SCE_SQL_USER2, "user2", FALSE }, { SCE_SQL_USER3, "user3", FALSE }, { SCE_SQL_USER4, "user4", FALSE }*/ }; static const HLKeyword highlighting_keywords_SQL[] = { { 0, "keywords", FALSE } }; #define highlighting_properties_SQL EMPTY_PROPERTIES /* TCL */ #define highlighting_lexer_TCL SCLEX_TCL static const HLStyle highlighting_styles_TCL[] = { { SCE_TCL_DEFAULT, "default", FALSE }, { SCE_TCL_COMMENT, "comment", FALSE }, { SCE_TCL_COMMENTLINE, "commentline", FALSE }, { SCE_TCL_NUMBER, "number", FALSE }, { SCE_TCL_OPERATOR, "operator", FALSE }, { SCE_TCL_IDENTIFIER, "identifier", FALSE }, { SCE_TCL_WORD_IN_QUOTE, "wordinquote", FALSE }, { SCE_TCL_IN_QUOTE, "inquote", FALSE }, { SCE_TCL_SUBSTITUTION, "substitution", FALSE }, { SCE_TCL_MODIFIER, "modifier", FALSE }, { SCE_TCL_EXPAND, "expand", FALSE }, { SCE_TCL_WORD, "wordtcl", FALSE }, { SCE_TCL_WORD2, "wordtk", FALSE }, { SCE_TCL_WORD3, "worditcl", FALSE }, { SCE_TCL_WORD4, "wordtkcmds", FALSE }, { SCE_TCL_WORD5, "wordexpand", FALSE }, { SCE_TCL_COMMENT_BOX, "commentbox", FALSE }, { SCE_TCL_BLOCK_COMMENT, "blockcomment", FALSE }, { SCE_TCL_SUB_BRACE, "subbrace", FALSE } /* these are for user-defined keywords we don't set yet */ /*{ SCE_TCL_WORD6, "user2", FALSE }, { SCE_TCL_WORD7, "user3", FALSE }, { SCE_TCL_WORD8, "user4", FALSE }*/ }; static const HLKeyword highlighting_keywords_TCL[] = { { 0, "tcl", FALSE }, { 1, "tk", FALSE }, { 2, "itcl", FALSE }, { 3, "tkcommands", FALSE }, { 4, "expand", FALSE } }; #define highlighting_properties_TCL EMPTY_PROPERTIES /* Txt2Tags */ #define highlighting_lexer_TXT2TAGS SCLEX_TXT2TAGS static const HLStyle highlighting_styles_TXT2TAGS[] = { { SCE_TXT2TAGS_DEFAULT, "default", FALSE }, { SCE_TXT2TAGS_LINE_BEGIN, "default", FALSE }, /* XIFME: remappings should be avoided */ { SCE_TXT2TAGS_PRECHAR, "default", FALSE }, { SCE_TXT2TAGS_STRONG1, "strong", FALSE }, { SCE_TXT2TAGS_STRONG2, "strong", FALSE }, { SCE_TXT2TAGS_EM1, "emphasis", FALSE }, { SCE_TXT2TAGS_EM2, "underlined", FALSE }, /* WTF? */ { SCE_TXT2TAGS_HEADER1, "header1", FALSE }, { SCE_TXT2TAGS_HEADER2, "header2", FALSE }, { SCE_TXT2TAGS_HEADER3, "header3", FALSE }, { SCE_TXT2TAGS_HEADER4, "header4", FALSE }, { SCE_TXT2TAGS_HEADER5, "header5", FALSE }, { SCE_TXT2TAGS_HEADER6, "header6", FALSE }, { SCE_TXT2TAGS_ULIST_ITEM, "ulist_item", FALSE }, { SCE_TXT2TAGS_OLIST_ITEM, "olist_item", FALSE }, { SCE_TXT2TAGS_BLOCKQUOTE, "blockquote", FALSE }, { SCE_TXT2TAGS_STRIKEOUT, "strikeout", FALSE }, { SCE_TXT2TAGS_HRULE, "hrule", FALSE }, { SCE_TXT2TAGS_LINK, "link", FALSE }, { SCE_TXT2TAGS_CODE, "code", FALSE }, { SCE_TXT2TAGS_CODE2, "code", FALSE }, { SCE_TXT2TAGS_CODEBK, "codebk", FALSE }, { SCE_TXT2TAGS_COMMENT, "comment", FALSE }, { SCE_TXT2TAGS_OPTION, "option", FALSE }, { SCE_TXT2TAGS_PREPROC, "preproc", FALSE }, { SCE_TXT2TAGS_POSTPROC, "postproc", FALSE } }; #define highlighting_keywords_TXT2TAGS EMPTY_KEYWORDS #define highlighting_properties_TXT2TAGS EMPTY_PROPERTIES /* VHDL */ #define highlighting_lexer_VHDL SCLEX_VHDL static const HLStyle highlighting_styles_VHDL[] = { { SCE_VHDL_DEFAULT, "default", FALSE }, { SCE_VHDL_COMMENT, "comment", FALSE }, { SCE_VHDL_COMMENTLINEBANG, "comment_line_bang", FALSE }, { SCE_VHDL_BLOCK_COMMENT, "block_comment", FALSE }, { SCE_VHDL_NUMBER, "number", FALSE }, { SCE_VHDL_STRING, "string", FALSE }, { SCE_VHDL_OPERATOR, "operator", FALSE }, { SCE_VHDL_IDENTIFIER, "identifier", FALSE }, { SCE_VHDL_STRINGEOL, "stringeol", FALSE }, { SCE_VHDL_KEYWORD, "keyword", FALSE }, { SCE_VHDL_STDOPERATOR, "stdoperator", FALSE }, { SCE_VHDL_ATTRIBUTE, "attribute", FALSE }, { SCE_VHDL_STDFUNCTION, "stdfunction", FALSE }, { SCE_VHDL_STDPACKAGE, "stdpackage", FALSE }, { SCE_VHDL_STDTYPE, "stdtype", FALSE }, { SCE_VHDL_USERWORD, "userword", FALSE } }; static const HLKeyword highlighting_keywords_VHDL[] = { { 0, "keywords", FALSE }, { 1, "operators", FALSE }, { 2, "attributes", FALSE }, { 3, "std_functions", FALSE }, { 4, "std_packages", FALSE }, { 5, "std_types", FALSE }, { 6, "userwords", FALSE }, }; #define highlighting_properties_VHDL EMPTY_PROPERTIES /* Verilog */ #define highlighting_lexer_VERILOG SCLEX_VERILOG static const HLStyle highlighting_styles_VERILOG[] = { { SCE_V_DEFAULT, "default", FALSE }, { SCE_V_COMMENT, "comment", FALSE }, { SCE_V_COMMENTLINE, "comment_line", FALSE }, { SCE_V_COMMENTLINEBANG, "comment_line_bang", FALSE }, { SCE_V_NUMBER, "number", FALSE }, { SCE_V_WORD, "word", FALSE }, { SCE_V_STRING, "string", FALSE }, { SCE_V_WORD2, "word2", FALSE }, { SCE_V_WORD3, "word3", FALSE }, { SCE_V_PREPROCESSOR, "preprocessor", FALSE }, { SCE_V_OPERATOR, "operator", FALSE }, { SCE_V_IDENTIFIER, "identifier", FALSE }, { SCE_V_STRINGEOL, "stringeol", FALSE }, { SCE_V_USER, "userword", FALSE }, { SCE_V_COMMENT_WORD, "comment_word", FALSE }, { SCE_V_INPUT, "input", FALSE }, { SCE_V_OUTPUT, "output", FALSE }, { SCE_V_INOUT, "inout", FALSE }, { SCE_V_PORT_CONNECT, "port_connect", FALSE } }; static const HLKeyword highlighting_keywords_VERILOG[] = { { 0, "word", FALSE }, { 1, "word2", FALSE }, { 2, "word3", FALSE }, { 4, "docComment", FALSE } }; #define highlighting_properties_VERILOG EMPTY_PROPERTIES /* XML */ #define highlighting_lexer_XML SCLEX_XML #define highlighting_styles_XML highlighting_styles_HTML static const HLKeyword highlighting_keywords_XML[] = { { 5, "sgml", FALSE } }; #define highlighting_properties_XML highlighting_properties_HTML /* YAML */ #define highlighting_lexer_YAML SCLEX_YAML static const HLStyle highlighting_styles_YAML[] = { { SCE_YAML_DEFAULT, "default", FALSE }, { SCE_YAML_COMMENT, "comment", FALSE }, { SCE_YAML_IDENTIFIER, "identifier", FALSE }, { SCE_YAML_KEYWORD, "keyword", FALSE }, { SCE_YAML_NUMBER, "number", FALSE }, { SCE_YAML_REFERENCE, "reference", FALSE }, { SCE_YAML_DOCUMENT, "document", FALSE }, { SCE_YAML_TEXT, "text", FALSE }, { SCE_YAML_ERROR, "error", FALSE }, { SCE_YAML_OPERATOR, "operator", FALSE } }; static const HLKeyword highlighting_keywords_YAML[] = { { 0, "keywords", FALSE } }; #define highlighting_properties_YAML EMPTY_PROPERTIES /* Zephir */ #define highlighting_lexer_ZEPHIR SCLEX_PHPSCRIPT #define highlighting_styles_ZEPHIR highlighting_styles_PHP #define highlighting_keywords_ZEPHIR highlighting_keywords_PHP #define highlighting_properties_ZEPHIR highlighting_properties_PHP /* AutoIt */ #define highlighting_lexer_AU3 SCLEX_AU3 static const HLStyle highlighting_styles_AU3[] = { { SCE_AU3_DEFAULT, "default", FALSE}, { SCE_AU3_COMMENT, "comment", FALSE}, { SCE_AU3_COMMENTBLOCK, "commentblock", FALSE}, { SCE_AU3_NUMBER, "number", FALSE}, { SCE_AU3_FUNCTION, "function", FALSE}, { SCE_AU3_KEYWORD, "keyword", FALSE}, { SCE_AU3_MACRO, "macro", FALSE}, { SCE_AU3_STRING, "string", FALSE}, { SCE_AU3_OPERATOR, "operator", FALSE}, { SCE_AU3_VARIABLE, "variable", FALSE}, { SCE_AU3_SENT, "sent", FALSE}, { SCE_AU3_PREPROCESSOR, "preprocessor", FALSE}, { SCE_AU3_SPECIAL, "special", FALSE}, { SCE_AU3_EXPAND, "expand", FALSE}, { SCE_AU3_COMOBJ, "comobj", FALSE}, { SCE_AU3_UDF, "udf", FALSE} }; static const HLKeyword highlighting_keywords_AU3[] = { { 0, "keywords", FALSE }, { 1, "functions", FALSE }, { 2, "macros", FALSE }, { 3, "sent", FALSE }, { 4, "preprocessor", FALSE }, { 5, "special", FALSE }, { 6, "expand", FALSE }, { 7, "udf", FALSE } }; #define highlighting_properties_AU3 EMPTY_PROPERTIES G_END_DECLS #endif /* GEANY_HIGHLIGHTING_MAPPINGS_H */ geany-2.0/src/utils.h0000644000175000017500000002634414514252267011520 00000000000000/* * utils.h - this file is part of Geany, a fast and lightweight IDE * * Copyright 2005 The Geany contributors * * This program 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; either version 2 of the License, or * (at your option) any later version. * * This program 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /** * @file: utils.h * General utility functions, non-GTK related. */ #ifndef GEANY_UTILS_H #define GEANY_UTILS_H 1 #include #include #include #include /* for GdkColor */ G_BEGIN_DECLS /** Returns @c TRUE if @a ptr is @c NULL or @c *ptr is @c FALSE. */ #define EMPTY(ptr) \ (!(ptr) || !*(ptr)) /** @deprecated 2013/08 - use @c !EMPTY() instead. */ #ifndef GEANY_DISABLE_DEPRECATED #define NZV(ptr) (!EMPTY(ptr)) #endif /** Assigns @a result to @a ptr, then frees the old value. * @a result can be an expression using the 'old' value of @a ptr. * E.g. @code SETPTR(str, g_strndup(str, 5)); @endcode **/ #define SETPTR(ptr, result) \ do {\ gpointer setptr_tmp = ptr;\ ptr = result;\ g_free(setptr_tmp);\ } while (0) #ifndef GEANY_DISABLE_DEPRECATED /** @deprecated 2011/11/15 - use SETPTR() instead. */ #define setptr(ptr, result) \ {\ gpointer setptr_tmp = ptr;\ ptr = result;\ g_free(setptr_tmp);\ } #endif /** Duplicates a string on the stack using @c g_alloca(). * Like glibc's @c strdupa(), but portable. * @note You must include @c string.h yourself. * @warning Don't use excessively or for long strings otherwise there may be stack exhaustion - * see the GLib docs for @c g_alloca(). */ #define utils_strdupa(str) \ strcpy(g_alloca(strlen(str) + 1), str) /* Get a keyfile setting, using the home keyfile if the key exists, * otherwise system keyfile. */ #define utils_get_setting(type, home, sys, group, key, default_val)\ (g_key_file_has_key(home, group, key, NULL)) ?\ utils_get_setting_##type(home, group, key, default_val) :\ utils_get_setting_##type(sys, group, key, default_val) /* ignore the case of filenames and paths under WIN32, causes errors if not */ #ifdef G_OS_WIN32 #define utils_filenamecmp(a, b) utils_str_casecmp((a), (b)) #else #define utils_filenamecmp(a, b) strcmp((a), (b)) #endif /** Iterates all the items in @a array using pointers. * @param item pointer to an item in @a array. * @param array C array to traverse. * @param len Length of the array. */ #define foreach_c_array(item, array, len) \ for (item = array; item < &array[len]; item++) /** Iterates all items in @a array. * @param type Type of @a item. * @param item pointer to item in @a array. * @param array @c GArray to traverse. */ #define foreach_array(type, item, array) \ foreach_c_array(item, ((type*)(gpointer)array->data), array->len) /** Iterates all the pointers in @a ptr_array. * @param item pointer in @a ptr_array. * @param idx @c guint index into @a ptr_array. * @param ptr_array @c GPtrArray to traverse. */ #define foreach_ptr_array(item, idx, ptr_array) \ for (idx = 0; idx < (ptr_array)->len && (item = g_ptr_array_index((ptr_array), idx), TRUE); ++idx) /** Iterates all the nodes in @a list. * @param node should be a (@c GList*). * @param list @c GList to traverse. */ #define foreach_list(node, list) \ for (node = list; node != NULL; node = node->next) /** Iterates all the nodes in @a list. * @param node should be a (@c GSList*). * @param list @c GSList to traverse. */ #define foreach_slist(node, list) \ foreach_list(node, list) /* Iterates all the nodes in @a list. Safe against removal during iteration * @param node should be a (@c GList*). * @param list @c GList to traverse. */ #define foreach_list_safe(node, list) \ for (GList *_node = (list), *_next = (list) ? (list)->next : NULL; \ (node = _node) != NULL; \ _node = _next, _next = _next ? _next->next : NULL) /** Iterates through each unsorted filename in a @c GDir. * @param filename (@c const @c gchar*) locale-encoded filename, without path. Do not modify or free. * @param dir @c GDir created with @c g_dir_open(). Call @c g_dir_close() afterwards. * @see utils_get_file_list() if you want a sorted list. * @since Geany 0.19. */ #define foreach_dir(filename, dir)\ for ((filename) = g_dir_read_name(dir); (filename) != NULL; (filename) = g_dir_read_name(dir)) /** Iterates through each character in @a string. * @param char_ptr Pointer to character. * @param string String to traverse. * @warning Doesn't include null terminating character. * @since Geany 0.19. */ #define foreach_str(char_ptr, string) \ for (char_ptr = string; *char_ptr; char_ptr++) /** Iterates a null-terminated string vector. * @param str_ptr @c gchar** pointer to string element. * @param strv Can be @c NULL. * @since Geany 0.20 */ #define foreach_strv(str_ptr, strv)\ if (!(strv)) {} else foreach_str(str_ptr, strv) /** Iterates from 0 to @a size. * @param i Integer. * @param size Number of iterations. * @since Geany 0.20. */ #define foreach_range(i, size) \ for (i = 0; i < size; i++) gboolean utils_str_equal(const gchar *a, const gchar *b); guint utils_string_replace_all(GString *haystack, const gchar *needle, const gchar *replace); GSList *utils_get_file_list(const gchar *path, guint *length, GError **error); GSList *utils_get_file_list_full(const gchar *path, gboolean full_path, gboolean sort, GError **error); gint utils_write_file(const gchar *filename, const gchar *text); gchar *utils_get_locale_from_utf8(const gchar *utf8_text); gchar *utils_get_utf8_from_locale(const gchar *locale_text); gchar *utils_remove_ext_from_filename(const gchar *filename); gint utils_mkdir(const gchar *path, gboolean create_parent_dirs); gboolean utils_get_setting_boolean(GKeyFile *config, const gchar *section, const gchar *key, const gboolean default_value); gint utils_get_setting_integer(GKeyFile *config, const gchar *section, const gchar *key, const gint default_value); gdouble utils_get_setting_double(GKeyFile *config, const gchar *section, const gchar *key, const gdouble default_value); gchar *utils_get_setting_string(GKeyFile *config, const gchar *section, const gchar *key, const gchar *default_value); gboolean utils_spawn_sync(const gchar *dir, gchar **argv, gchar **env, GSpawnFlags flags, GSpawnChildSetupFunc child_setup, gpointer user_data, gchar **std_out, gchar **std_err, gint *exit_status, GError **error); gboolean utils_spawn_async(const gchar *dir, gchar **argv, gchar **env, GSpawnFlags flags, GSpawnChildSetupFunc child_setup, gpointer user_data, GPid *child_pid, GError **error); gchar *utils_utf8_strdown(const gchar *str); gint utils_str_casecmp(const gchar *s1, const gchar *s2); gchar *utils_get_date_time(const gchar *format, time_t *time_to_use); void utils_open_browser(const gchar *uri); guint utils_string_replace_first(GString *haystack, const gchar *needle, const gchar *replace); gchar *utils_str_middle_truncate(const gchar *string, guint truncate_length); gchar *utils_str_remove_chars(gchar *string, const gchar *chars); gchar **utils_copy_environment(const gchar **exclude_vars, const gchar *first_varname, ...) G_GNUC_NULL_TERMINATED; gchar *utils_find_open_xml_tag(const gchar sel[], gint size); const gchar *utils_find_open_xml_tag_pos(const gchar sel[], gint size); gchar *utils_get_real_path(const gchar *file_name); gchar **utils_strv_shorten_file_list(gchar **file_names, gssize file_names_len); #ifdef GEANY_PRIVATE typedef enum { RESOURCE_DIR_DATA, RESOURCE_DIR_ICON, RESOURCE_DIR_DOC, RESOURCE_DIR_LOCALE, RESOURCE_DIR_PLUGIN, RESOURCE_DIR_LIBEXEC, RESOURCE_DIR_COUNT } GeanyResourceDirType; gint utils_get_line_endings(const gchar* buffer, gsize size); gboolean utils_isbrace(gchar c, gboolean include_angles); gboolean utils_is_opening_brace(gchar c, gboolean include_angles); gboolean utils_is_short_html_tag(const gchar *tag_name); void utils_ensure_same_eol_characters(GString *string, gint target_eol_mode); const gchar *utils_get_eol_char(gint eol_mode); const gchar *utils_get_eol_name(gint eol_mode); const gchar *utils_get_eol_short_name(gint eol_mode); gboolean utils_atob(const gchar *str); void utils_tidy_path(gchar *filename); gboolean utils_is_absolute_path(const gchar *path); const gchar *utils_path_skip_root(const gchar *path); gdouble utils_scale_round(gdouble val, gdouble factor); gchar utils_brace_opposite(gchar ch); gint utils_string_find(GString *haystack, gint start, gint end, const gchar *needle); gint utils_string_replace(GString *str, gint pos, gint len, const gchar *replace); guint utils_string_regex_replace_all(GString *haystack, GRegex *regex, guint match_num, const gchar *replace, gboolean literal); void utils_str_replace_all(gchar **haystack, const gchar *needle, const gchar *replacement); gint utils_strpos(const gchar* haystack, const gchar *needle); gchar *utils_get_initials(const gchar *name); gchar *utils_get_hex_from_color(GdkColor *color); const gchar *utils_get_default_dir_utf8(void); gchar *utils_get_current_file_dir_utf8(void); void utils_beep(void); gchar *utils_make_human_readable_str(guint64 size, gulong block_size, gulong display_unit); gboolean utils_parse_color(const gchar *spec, GdkColor *color); gint utils_color_to_bgr(const GdkColor *color); gint utils_parse_color_to_bgr(const gchar *spec); gchar *utils_get_current_time_string(gboolean include_microseconds); GIOChannel *utils_set_up_io_channel(gint fd, GIOCondition cond, gboolean nblock, GIOFunc func, gpointer data); gboolean utils_str_replace_escape(gchar *string, gboolean keep_backslash); gboolean utils_wrap_string(gchar *string, gint wrapstart); void utils_free_pointers(gsize arg_count, ...) G_GNUC_NULL_TERMINATED; gchar **utils_strv_new(const gchar *first, ...) G_GNUC_NULL_TERMINATED; gchar **utils_strv_join(gchar **first, gchar **second) G_GNUC_WARN_UNUSED_RESULT; gchar *utils_strv_find_common_prefix(gchar **strv, gssize strv_len) G_GNUC_WARN_UNUSED_RESULT; gchar *utils_strv_find_lcs(gchar **strv, gssize strv_len, const gchar *delim) G_GNUC_WARN_UNUSED_RESULT; GSList *utils_get_config_files(const gchar *subdir); gchar *utils_get_help_url(const gchar *suffix); gboolean utils_str_has_upper(const gchar *str); gint utils_is_file_writable(const gchar *locale_filename); const gchar *utils_get_uri_file_prefix(void); gchar *utils_get_path_from_uri(const gchar *uri); gboolean utils_is_uri(const gchar *uri); gboolean utils_is_remote_path(const gchar *path); GDate *utils_parse_date(const gchar *input); gchar *utils_parse_and_format_build_date(const gchar *input); gchar *utils_get_user_config_dir(void); const gchar *utils_resource_dir(GeanyResourceDirType type); void utils_start_new_geany_instance(const gchar *doc_path); gchar *utils_get_os_info_string(void); #endif /* GEANY_PRIVATE */ G_END_DECLS #endif /* GEANY_UTILS_H */ geany-2.0/src/prefs.c0000644000175000017500000021365314514252267011473 00000000000000/* * prefs.c - this file is part of Geany, a fast and lightweight IDE * * Copyright 2005 The Geany contributors * * This program 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; either version 2 of the License, or * (at your option) any later version. * * This program 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /* * @file prefs.h * Preferences dialog. */ /* * Preferences dialog support functions. * New 'simple' prefs should use Stash code in keyfile.c - init_pref_groups(). */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include "prefs.h" #include "app.h" #include "dialogs.h" #include "documentprivate.h" #include "editor.h" #include "encodingsprivate.h" #include "filetypes.h" #include "geanywraplabel.h" #include "keybindingsprivate.h" #include "keyfile.h" #include "msgwindow.h" #include "prefs.h" #include "printing.h" #include "sidebar.h" #include "stash.h" #include "support.h" #include "templates.h" #include "toolbar.h" #include "tools.h" #include "ui_utils.h" #include "utils.h" #include "vte.h" #include "osx.h" #include #include #include #include GeanyPrefs prefs; GeanyToolPrefs tool_prefs; typedef struct { GtkTreeStore *store; GtkTreeView *tree; gboolean edited; } KbData; static KbData global_kb_data = { NULL, NULL, FALSE }; static GtkTreeView *various_treeview = NULL; static GeanyKeyBinding *kb_index(guint gidx, guint kid); static void kb_cell_edited_cb(GtkCellRendererText *cellrenderertext, gchar *path, gchar *new_text, KbData *kbdata); static gboolean kb_grab_key_dialog_key_press_cb(GtkWidget *dialog, GdkEventKey *event, GtkLabel *label); static void kb_change_iter_shortcut(KbData *kbdata, GtkTreeIter *iter, const gchar *new_text); static gboolean kb_find_duplicate(GtkTreeStore *store, GtkWidget *parent, GtkTreeIter *old_iter, guint key, GdkModifierType mods, const gchar *shortcut); static void on_toolbar_show_toggled(GtkToggleButton *togglebutton, gpointer user_data); static void on_show_notebook_tabs_toggled(GtkToggleButton *togglebutton, gpointer user_data); static void on_enable_plugins_toggled(GtkToggleButton *togglebutton, gpointer user_data); static void on_use_folding_toggled(GtkToggleButton *togglebutton, gpointer user_data); static void on_check_line_end_toggled(GtkToggleButton *togglebutton, gpointer user_data); static void on_open_encoding_toggled(GtkToggleButton *togglebutton, gpointer user_data); static void on_sidebar_visible_toggled(GtkToggleButton *togglebutton, gpointer user_data); static void on_prefs_print_radio_button_toggled(GtkToggleButton *togglebutton, gpointer user_data); static void on_prefs_print_page_header_toggled(GtkToggleButton *togglebutton, gpointer user_data); static void open_preferences_help(void); typedef enum PrefCallbackAction { PREF_DISPLAY, PREF_UPDATE } PrefCallbackAction; /* Synchronize Stash settings with widgets (see keyfile.c - init_pref_groups()). */ static void prefs_action(PrefCallbackAction action) { StashGroup *group; guint i; foreach_ptr_array(group, i, pref_groups) { switch (action) { case PREF_DISPLAY: stash_group_display(group, ui_widgets.prefs_dialog); break; case PREF_UPDATE: stash_group_update(group, ui_widgets.prefs_dialog); break; } } switch (action) { case PREF_DISPLAY: stash_tree_display(various_treeview); break; case PREF_UPDATE: stash_tree_update(various_treeview); break; } } enum { KB_TREE_ACTION, KB_TREE_SHORTCUT, KB_TREE_INDEX, KB_TREE_EDITABLE, KB_TREE_WEIGHT, KB_TREE_COLUMNS }; static void kb_tree_view_change_button_clicked_cb(GtkWidget *button, KbData *kbdata) { GtkTreeModel *model; GtkTreeIter iter; GtkTreeSelection *selection; gchar *name; selection = gtk_tree_view_get_selection(kbdata->tree); if (gtk_tree_selection_get_selected(selection, &model, &iter)) { if (gtk_tree_model_iter_has_child(model, &iter)) { /* double click on a section to expand or collapse it */ GtkTreePath *path = gtk_tree_model_get_path(model, &iter); if (gtk_tree_view_row_expanded(kbdata->tree, path)) gtk_tree_view_collapse_row(kbdata->tree, path); else gtk_tree_view_expand_row(kbdata->tree, path, FALSE); gtk_tree_path_free(path); return; } gtk_tree_model_get(model, &iter, KB_TREE_ACTION, &name, -1); if (name != NULL) { GtkWidget *dialog; GtkWidget *label; GtkWidget *accel_label; gchar *str; dialog = gtk_dialog_new_with_buttons(_("Grab Key"), GTK_WINDOW(ui_widgets.prefs_dialog), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, NULL); str = g_strdup_printf( _("Press the combination of the keys you want to use for \"%s\"."), name); label = gtk_label_new(str); gtk_misc_set_padding(GTK_MISC(label), 5, 10); gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), label); accel_label = gtk_label_new(""); gtk_misc_set_padding(GTK_MISC(accel_label), 5, 10); gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), accel_label); g_signal_connect(dialog, "key-press-event", G_CALLBACK(kb_grab_key_dialog_key_press_cb), accel_label); gtk_widget_show_all(dialog); if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { const gchar *new_text = gtk_label_get_text(GTK_LABEL(accel_label)); kb_change_iter_shortcut(kbdata, &iter, new_text); } gtk_widget_destroy(dialog); g_free(str); g_free(name); } } } static void kb_show_popup_menu(KbData *kbdata, GtkWidget *widget, GdkEventButton *event) { static GtkWidget *menu = NULL; if (menu == NULL) { GtkWidget *item; menu = gtk_menu_new(); item = ui_image_menu_item_new(GTK_STOCK_ADD, _("_Expand All")); gtk_widget_show(item); gtk_container_add(GTK_CONTAINER(menu), item); g_signal_connect_swapped(item, "activate", G_CALLBACK(gtk_tree_view_expand_all), kbdata->tree); item = ui_image_menu_item_new(GTK_STOCK_REMOVE, _("_Collapse All")); gtk_widget_show(item); gtk_container_add(GTK_CONTAINER(menu), item); g_signal_connect_swapped(item, "activate", G_CALLBACK(gtk_tree_view_collapse_all), kbdata->tree); gtk_menu_attach_to_widget(GTK_MENU(menu), widget, NULL); } gtk_menu_popup_at_pointer(GTK_MENU(menu), (GdkEvent *) event); } static gboolean kb_popup_menu_cb(GtkWidget *widget, KbData *kbdata) { kb_show_popup_menu(kbdata, widget, NULL); return TRUE; } static gboolean kb_tree_view_button_press_event_cb(GtkWidget *widget, GdkEventButton *event, KbData *kbdata) { if (event->button == 3 && event->type == GDK_BUTTON_PRESS) { kb_show_popup_menu(kbdata, widget, event); return TRUE; } else if (event->type == GDK_2BUTTON_PRESS) { kb_tree_view_change_button_clicked_cb(NULL, kbdata); return TRUE; } return FALSE; } static void kb_init_tree(KbData *kbdata) { GtkCellRenderer *renderer; GtkTreeViewColumn *column; kbdata->tree = GTK_TREE_VIEW(ui_lookup_widget(ui_widgets.prefs_dialog, "treeview7")); kbdata->store = gtk_tree_store_new(KB_TREE_COLUMNS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT, G_TYPE_BOOLEAN, G_TYPE_INT); gtk_tree_view_set_model(GTK_TREE_VIEW(kbdata->tree), GTK_TREE_MODEL(kbdata->store)); g_object_unref(kbdata->store); renderer = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes(_("Action"), renderer, "text", KB_TREE_ACTION, "weight", KB_TREE_WEIGHT, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(kbdata->tree), column); renderer = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes(_("Shortcut"), renderer, "text", KB_TREE_SHORTCUT, "editable", KB_TREE_EDITABLE, "weight", KB_TREE_WEIGHT, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(kbdata->tree), column); /* set policy settings for the scrolled window around the treeview again, because glade * doesn't keep the settings */ gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW(ui_lookup_widget(ui_widgets.prefs_dialog, "scrolledwindow8")), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); g_signal_connect(renderer, "edited", G_CALLBACK(kb_cell_edited_cb), kbdata); g_signal_connect(kbdata->tree, "button-press-event", G_CALLBACK(kb_tree_view_button_press_event_cb), kbdata); g_signal_connect(kbdata->tree, "popup-menu", G_CALLBACK(kb_popup_menu_cb), kbdata); g_signal_connect(ui_lookup_widget(ui_widgets.prefs_dialog, "button2"), "clicked", G_CALLBACK(kb_tree_view_change_button_clicked_cb), kbdata); } static void kb_set_shortcut(GtkTreeStore *store, GtkTreeIter *iter, guint key, GdkModifierType mods) { gchar *key_string = gtk_accelerator_name(key, mods); GtkTreeIter parent; guint kid, gid; GeanyKeyBinding *kb; gboolean bold; gtk_tree_store_set(store, iter, KB_TREE_SHORTCUT, key_string, -1); g_free(key_string); gtk_tree_model_get(GTK_TREE_MODEL(store), iter, KB_TREE_INDEX, &kid, -1); gtk_tree_model_iter_parent(GTK_TREE_MODEL(store), &parent, iter); gtk_tree_model_get(GTK_TREE_MODEL(store), &parent, KB_TREE_INDEX, &gid, -1); kb = kb_index(gid, kid); bold = key != kb->default_key || mods != kb->default_mods; gtk_tree_store_set(store, iter, KB_TREE_WEIGHT, bold ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL, -1); } void prefs_kb_search_name(const gchar *search) { GtkTreeIter iter; gboolean valid; GtkTreeModel *model; KbData *kbdata = &global_kb_data; model = gtk_tree_view_get_model(kbdata->tree); valid = gtk_tree_model_get_iter_first(model, &iter); while (valid) { gchar *name; gtk_tree_model_get(model, &iter, KB_TREE_ACTION, &name, -1); if (g_strcmp0(name, search) == 0) { GtkTreePath *path = gtk_tree_model_get_path(model, &iter); gtk_tree_view_scroll_to_cell(kbdata->tree, path, NULL, TRUE, .0f, .0f); gtk_tree_path_free(path); g_free(name); break; } g_free(name); valid = gtk_tree_model_iter_next(model, &iter); } } static void kb_init(KbData *kbdata) { GtkTreeIter parent, iter; gsize g, i; gchar *label; GeanyKeyGroup *group; GeanyKeyBinding *kb; if (kbdata->store == NULL) kb_init_tree(kbdata); foreach_ptr_array(group, g, keybinding_groups) { gtk_tree_store_append(kbdata->store, &parent, NULL); gtk_tree_store_set(kbdata->store, &parent, KB_TREE_ACTION, group->label, KB_TREE_INDEX, g, -1); foreach_ptr_array(kb, i, group->key_items) { label = keybindings_get_label(kb); gtk_tree_store_append(kbdata->store, &iter, &parent); gtk_tree_store_set(kbdata->store, &iter, KB_TREE_ACTION, label, KB_TREE_EDITABLE, TRUE, KB_TREE_INDEX, kb->id, -1); kb_set_shortcut(kbdata->store, &iter, kb->key, kb->mods); g_free(label); } } gtk_tree_view_expand_all(GTK_TREE_VIEW(kbdata->tree)); } /* note: new 'simple' prefs should use Stash code in keyfile.c */ static void prefs_init_dialog(void) { GtkWidget *widget; GdkColor color = {0}; /* Synchronize with Stash settings */ prefs_action(PREF_DISPLAY); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "label_project_indent_warning"); ui_widget_show_hide(widget, app->project != NULL); /* General settings */ /* startup */ widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_load_session"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), prefs.load_session); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_project_file_in_basedir"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), project_prefs.project_file_in_basedir); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_save_win_pos"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), prefs.save_winpos); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_save_win_geom"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), prefs.save_wingeom); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_ask_for_quit"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), prefs.confirm_exit); /* behaviour */ widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_beep"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), prefs.beep_on_errors); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_switch_pages"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), prefs.switch_to_status); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_suppress_status_msgs"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), prefs.suppress_status_messages); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_auto_focus"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), prefs.auto_focus); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_contextaction"); gtk_entry_set_text(GTK_ENTRY(widget), tool_prefs.context_action_cmd); project_setup_prefs(); /* project files path */ /* Interface settings */ widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_sidebar_visible"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), ui_prefs.sidebar_visible); on_sidebar_visible_toggled(GTK_TOGGLE_BUTTON(widget), NULL); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_list_symbol"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), interface_prefs.sidebar_symbol_visible); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_list_openfiles"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), interface_prefs.sidebar_openfiles_visible); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "tagbar_font"); gtk_font_button_set_font_name(GTK_FONT_BUTTON(widget), interface_prefs.tagbar_font); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "msgwin_font"); gtk_font_button_set_font_name(GTK_FONT_BUTTON(widget), interface_prefs.msgwin_font); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "editor_font"); gtk_font_button_set_font_name(GTK_FONT_BUTTON(widget), interface_prefs.editor_font); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "spin_long_line"); gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget), editor_prefs.long_line_column); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_long_line"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.long_line_enabled); switch (editor_prefs.long_line_type) { case 0: widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_long_line_line"); break; case 1: widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_long_line_background"); break; } gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), TRUE); utils_parse_color(editor_prefs.long_line_color, &color); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "long_line_color"); gtk_color_button_set_color(GTK_COLOR_BUTTON(widget), &color); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_show_notebook_tabs"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), interface_prefs.show_notebook_tabs); /* disable following setting if notebook tabs are hidden */ on_show_notebook_tabs_toggled(GTK_TOGGLE_BUTTON( ui_lookup_widget(ui_widgets.prefs_dialog, "check_show_notebook_tabs")), NULL); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_show_tab_cross"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), file_prefs.show_tab_cross); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_tab_editor"); gtk_combo_box_set_active(GTK_COMBO_BOX(widget), interface_prefs.tab_pos_editor); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_tab_msgwin"); gtk_combo_box_set_active(GTK_COMBO_BOX(widget), interface_prefs.tab_pos_msgwin); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_tab_sidebar"); gtk_combo_box_set_active(GTK_COMBO_BOX(widget), interface_prefs.tab_pos_sidebar); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_statusbar_visible"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), interface_prefs.statusbar_visible); /* Toolbar settings */ widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_toolbar_show"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), toolbar_prefs.visible); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_toolbar_in_menu"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), toolbar_prefs.append_to_menu); switch (toolbar_prefs.icon_style) { case 0: widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_toolbar_image"); break; case 1: widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_toolbar_text"); break; default: widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_toolbar_imagetext"); break; } if (toolbar_prefs.use_gtk_default_style) widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_toolbar_style_default"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), TRUE); switch (toolbar_prefs.icon_size) { case GTK_ICON_SIZE_LARGE_TOOLBAR: widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_toolbar_large"); break; case GTK_ICON_SIZE_SMALL_TOOLBAR: widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_toolbar_small"); break; default: widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_toolbar_verysmall"); break; } if (toolbar_prefs.use_gtk_default_icon) widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_toolbar_icon_default"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), TRUE); /* disable elements if toolbar is hidden */ on_toolbar_show_toggled(GTK_TOGGLE_BUTTON( ui_lookup_widget(ui_widgets.prefs_dialog, "check_toolbar_show")), NULL); /* Files settings */ if (file_prefs.tab_order_ltr) widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_tab_right"); else widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_tab_left"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), TRUE); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_tab_beside"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), file_prefs.tab_order_beside); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_new_encoding"); ui_encodings_combo_box_set_active_encoding(GTK_COMBO_BOX(widget), file_prefs.default_new_encoding); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_open_encoding"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), (file_prefs.default_open_encoding >= 0) ? TRUE : FALSE); on_open_encoding_toggled(GTK_TOGGLE_BUTTON(widget), NULL); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_open_encoding"); if (file_prefs.default_open_encoding >= 0) { ui_encodings_combo_box_set_active_encoding(GTK_COMBO_BOX(widget), file_prefs.default_open_encoding); } else ui_encodings_combo_box_set_active_encoding(GTK_COMBO_BOX(widget), GEANY_ENCODING_UTF_8); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_eol"); if (file_prefs.default_eol_character >= 0 && file_prefs.default_eol_character < 3) { gtk_combo_box_set_active(GTK_COMBO_BOX(widget), file_prefs.default_eol_character); } else gtk_combo_box_set_active(GTK_COMBO_BOX(widget), GEANY_DEFAULT_EOL_CHARACTER); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_trailing_spaces"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), file_prefs.strip_trailing_spaces); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_new_line"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), file_prefs.final_new_line); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_ensure_convert_new_lines"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), file_prefs.ensure_convert_new_lines); /* Editor settings */ widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_toggle_mark"); gtk_entry_set_text(GTK_ENTRY(widget), editor_prefs.comment_toggle_mark); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_replace_tabs"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), file_prefs.replace_tabs); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_indent"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.show_indent_guide); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_white_space"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.show_white_space); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_line_end"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.show_line_endings); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_line_endings_only_when_differ"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.show_line_endings_only_when_differ); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_line_numbers"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.show_linenumber_margin); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_markers_margin"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.show_markers_margin); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_scroll_stop_at_last_line"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.scroll_stop_at_last_line); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_line_wrapping"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.line_wrapping); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_complete_snippets"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.complete_snippets); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_xmltag"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.auto_close_xml_tags); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_folding"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.folding); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_unfold_children"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.unfold_all_children); on_use_folding_toggled(GTK_TOGGLE_BUTTON( ui_lookup_widget(ui_widgets.prefs_dialog, "check_folding")), NULL); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_disable_dnd"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.disable_dnd); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_smart_home"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.smart_home_key); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_newline_strip"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.newline_strip); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_indicators"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.use_indicators); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_auto_multiline"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.auto_continue_multiline); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_symbol_auto_completion"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.auto_complete_symbols); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "spin_symbollistheight"); gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget), editor_prefs.symbolcompletion_max_height); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "spin_symbol_complete_chars"); gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget), editor_prefs.symbolcompletion_min_chars); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "spin_line_break"); gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget), editor_prefs.line_break_column); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_autoclose_parenthesis"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), (editor_prefs.autoclose_chars & GEANY_AC_PARENTHESIS)); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_autoclose_cbracket"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), (editor_prefs.autoclose_chars & GEANY_AC_CBRACKET)); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_autoclose_sbracket"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), (editor_prefs.autoclose_chars & GEANY_AC_SBRACKET)); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_autoclose_squote"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), (editor_prefs.autoclose_chars & GEANY_AC_SQUOTE)); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_autoclose_dquote"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), (editor_prefs.autoclose_chars & GEANY_AC_DQUOTE)); /* Tools Settings */ if (tool_prefs.term_cmd) gtk_entry_set_text(GTK_ENTRY(ui_lookup_widget(ui_widgets.prefs_dialog, "entry_com_term")), tool_prefs.term_cmd); if (tool_prefs.browser_cmd) gtk_entry_set_text(GTK_ENTRY(ui_lookup_widget(ui_widgets.prefs_dialog, "entry_browser")), tool_prefs.browser_cmd); if (tool_prefs.grep_cmd) gtk_entry_set_text(GTK_ENTRY(ui_lookup_widget(ui_widgets.prefs_dialog, "entry_grep")), tool_prefs.grep_cmd); /* Template settings */ widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_developer"); gtk_entry_set_text(GTK_ENTRY(widget), template_prefs.developer); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_company"); gtk_entry_set_text(GTK_ENTRY(widget), template_prefs.company); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_mail"); gtk_entry_set_text(GTK_ENTRY(widget), template_prefs.mail); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_initial"); gtk_entry_set_text(GTK_ENTRY(widget), template_prefs.initials); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_version"); gtk_entry_set_text(GTK_ENTRY(widget), template_prefs.version); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_year"); gtk_entry_set_text(GTK_ENTRY(widget), template_prefs.year_format); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_date"); gtk_entry_set_text(GTK_ENTRY(widget), template_prefs.date_format); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_datetime"); gtk_entry_set_text(GTK_ENTRY(widget), template_prefs.datetime_format); /* Keybindings */ kb_init(&global_kb_data); /* Printing */ { GtkWidget *widget_gtk = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_print_gtk"); if (printing_prefs.use_gtk_printing) widget = widget_gtk; else widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_print_external"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), TRUE); on_prefs_print_radio_button_toggled(GTK_TOGGLE_BUTTON(widget_gtk), NULL); } if (printing_prefs.external_print_cmd) gtk_entry_set_text( GTK_ENTRY(ui_lookup_widget(ui_widgets.prefs_dialog, "entry_print_external_cmd")), printing_prefs.external_print_cmd); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_print_linenumbers"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), printing_prefs.print_line_numbers); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_print_pagenumbers"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), printing_prefs.print_page_numbers); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_print_pageheader"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), printing_prefs.print_page_header); on_prefs_print_page_header_toggled(GTK_TOGGLE_BUTTON(widget), NULL); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_print_basename"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), printing_prefs.page_header_basename); if (printing_prefs.page_header_datefmt) gtk_entry_set_text( GTK_ENTRY(ui_lookup_widget(ui_widgets.prefs_dialog, "entry_print_dateformat")), printing_prefs.page_header_datefmt); #ifndef HAVE_PLUGINS gtk_widget_set_sensitive(ui_lookup_widget(ui_widgets.prefs_dialog, "check_plugins"), FALSE); #endif on_enable_plugins_toggled(GTK_TOGGLE_BUTTON( ui_lookup_widget(ui_widgets.prefs_dialog, "check_plugins")), NULL); #ifdef HAVE_VTE /* make VTE switch visible only when VTE is compiled in, it is hidden by default */ widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_vte"); gtk_widget_show(widget); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), vte_info.load_vte); /* VTE settings */ if (vte_info.have_vte) { VteConfig *vc = &vte_config; widget = ui_lookup_widget(ui_widgets.prefs_dialog, "font_term"); gtk_font_button_set_font_name(GTK_FONT_BUTTON(widget), vc->font); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "color_fore"); gtk_color_button_set_color(GTK_COLOR_BUTTON(widget), &vc->colour_fore); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "color_back"); gtk_color_button_set_color(GTK_COLOR_BUTTON(widget), &vc->colour_back); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "spin_scrollback"); gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget), vc->scrollback_lines); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_shell"); gtk_entry_set_text(GTK_ENTRY(widget), vc->shell); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_scroll_key"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), vc->scroll_on_key); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_scroll_out"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), vc->scroll_on_out); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_enable_bash_keys"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), vc->enable_bash_keys); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_ignore_menu_key"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), vc->ignore_menu_bar_accel); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_follow_path"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), vc->follow_path); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_run_in_vte"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), vc->run_in_vte); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_skip_script"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), vc->skip_run_script); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_cursor_blinks"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), vc->cursor_blinks); } #endif } /* note: uses group index, not group id, unlike keybindings_lookup_item(). */ static GeanyKeyBinding *kb_index(guint gidx, guint kid) { GeanyKeyGroup *group; group = g_ptr_array_index(keybinding_groups, gidx); return keybindings_get_item(group, kid); } /* read the treeview shortcut fields into keybindings */ static void kb_update(KbData *kbdata) { GtkTreeModel *model = GTK_TREE_MODEL(kbdata->store); GtkTreeIter child, parent; guint gid = 0; /* get first parent */ if (! gtk_tree_model_iter_children(model, &parent, NULL)) return; /* foreach parent */ while (TRUE) { /* get first child */ if (! gtk_tree_model_iter_children(model, &child, &parent)) return; /* foreach child */ while (TRUE) { guint kid; gchar *str; guint key; GdkModifierType mods; GeanyKeyBinding *kb; gtk_tree_model_get(model, &child, KB_TREE_INDEX, &kid, KB_TREE_SHORTCUT, &str, -1); gtk_accelerator_parse(str, &key, &mods); g_free(str); kb = kb_index(gid, kid); if (kb->key != key || kb->mods != mods) keybindings_update_combo(kb, key, mods); if (! gtk_tree_model_iter_next(model, &child)) break; } if (! gtk_tree_model_iter_next(model, &parent)) return; gid++; } } /* * callbacks */ /* note: new 'simple' prefs should use Stash code in keyfile.c */ static void on_prefs_dialog_response(GtkDialog *dialog, gint response, gpointer user_data) { if (response == GTK_RESPONSE_OK || response == GTK_RESPONSE_APPLY) { GtkWidget *widget; guint i; gboolean autoclose_brackets[5]; gboolean old_invert_all = interface_prefs.highlighting_invert_all; gboolean old_sidebar_pos = interface_prefs.sidebar_pos; GeanyDocument *doc = document_get_current(); /* Synchronize Stash settings */ prefs_action(PREF_UPDATE); if (interface_prefs.highlighting_invert_all != old_invert_all) filetypes_reload(); if (interface_prefs.sidebar_pos != old_sidebar_pos) ui_swap_sidebar_pos(); widget = ui_lookup_widget(main_widgets.window, "vpaned1"); gtk_orientable_set_orientation(GTK_ORIENTABLE(widget), interface_prefs.msgwin_orientation); /* General settings */ /* startup */ widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_load_session"); prefs.load_session = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_project_file_in_basedir"); project_prefs.project_file_in_basedir = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_save_win_pos"); prefs.save_winpos = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_save_win_geom"); prefs.save_wingeom = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_ask_for_quit"); prefs.confirm_exit = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); /* behaviour */ widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_beep"); prefs.beep_on_errors = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_switch_pages"); prefs.switch_to_status = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_suppress_status_msgs"); prefs.suppress_status_messages = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_auto_focus"); prefs.auto_focus = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_contextaction"); g_free(tool_prefs.context_action_cmd); tool_prefs.context_action_cmd = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget))); project_apply_prefs(); /* project file path */ /* Interface settings */ widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_sidebar_visible"); ui_prefs.sidebar_visible = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_list_symbol"); interface_prefs.sidebar_symbol_visible = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_list_openfiles"); interface_prefs.sidebar_openfiles_visible = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_long_line"); editor_prefs.long_line_enabled = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_long_line_line"); if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) editor_prefs.long_line_type = 0; else /* now only the "background" radio remains */ editor_prefs.long_line_type = 1; if (editor_prefs.long_line_column == 0) editor_prefs.long_line_enabled = FALSE; widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_show_notebook_tabs"); interface_prefs.show_notebook_tabs = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_show_tab_cross"); file_prefs.show_tab_cross = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_tab_editor"); interface_prefs.tab_pos_editor = gtk_combo_box_get_active(GTK_COMBO_BOX(widget)); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_tab_msgwin"); interface_prefs.tab_pos_msgwin = gtk_combo_box_get_active(GTK_COMBO_BOX(widget)); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_tab_sidebar"); interface_prefs.tab_pos_sidebar = gtk_combo_box_get_active(GTK_COMBO_BOX(widget)); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_statusbar_visible"); interface_prefs.statusbar_visible = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "spin_tab_label_len"); interface_prefs.tab_label_len = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget)); /* Toolbar settings */ widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_toolbar_show"); toolbar_prefs.visible = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_toolbar_in_menu"); toolbar_prefs.append_to_menu = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_toolbar_style_default"); toolbar_prefs.use_gtk_default_style = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); if (! toolbar_prefs.use_gtk_default_style) { widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_toolbar_imagetext"); if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) toolbar_prefs.icon_style = 2; else { widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_toolbar_image"); if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) toolbar_prefs.icon_style = 0; else /* now only the text only radio remains, so set text only */ toolbar_prefs.icon_style = 1; } } widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_toolbar_icon_default"); toolbar_prefs.use_gtk_default_icon = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); if (! toolbar_prefs.use_gtk_default_icon) { toolbar_prefs.icon_size = GTK_ICON_SIZE_LARGE_TOOLBAR; widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_toolbar_large"); if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) toolbar_prefs.icon_size = GTK_ICON_SIZE_LARGE_TOOLBAR; else { widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_toolbar_small"); if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) toolbar_prefs.icon_size = GTK_ICON_SIZE_SMALL_TOOLBAR; else toolbar_prefs.icon_size = GTK_ICON_SIZE_MENU; } } /* Files settings */ widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_tab_right"); file_prefs.tab_order_ltr = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_tab_beside"); file_prefs.tab_order_beside = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_new_encoding"); file_prefs.default_new_encoding = ui_encodings_combo_box_get_active_encoding(GTK_COMBO_BOX(widget)); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_open_encoding"); if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) { widget = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_open_encoding"); file_prefs.default_open_encoding = ui_encodings_combo_box_get_active_encoding(GTK_COMBO_BOX(widget)); } else file_prefs.default_open_encoding = -1; widget = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_eol"); file_prefs.default_eol_character = gtk_combo_box_get_active(GTK_COMBO_BOX(widget)); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_trailing_spaces"); file_prefs.strip_trailing_spaces = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_new_line"); file_prefs.final_new_line = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_ensure_convert_new_lines"); file_prefs.ensure_convert_new_lines = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_replace_tabs"); file_prefs.replace_tabs = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); /* Editor settings */ widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_toggle_mark"); SETPTR(editor_prefs.comment_toggle_mark, gtk_editable_get_chars(GTK_EDITABLE(widget), 0, -1)); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "spin_long_line"); /* note: use stash for new code - it updates spin buttons itself */ gtk_spin_button_update(GTK_SPIN_BUTTON(widget)); editor_prefs.long_line_column = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget)); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_folding"); editor_prefs.folding = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); ui_update_fold_items(); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_unfold_children"); editor_prefs.unfold_all_children = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_indent"); editor_prefs.show_indent_guide = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_white_space"); editor_prefs.show_white_space = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_line_end"); editor_prefs.show_line_endings = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_line_endings_only_when_differ"); editor_prefs.show_line_endings_only_when_differ = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(widget)); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_line_numbers"); editor_prefs.show_linenumber_margin = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_markers_margin"); editor_prefs.show_markers_margin = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_scroll_stop_at_last_line"); editor_prefs.scroll_stop_at_last_line = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_line_wrapping"); editor_prefs.line_wrapping = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_complete_snippets"); editor_prefs.complete_snippets = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_xmltag"); editor_prefs.auto_close_xml_tags = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_indicators"); editor_prefs.use_indicators = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_disable_dnd"); editor_prefs.disable_dnd = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_smart_home"); editor_prefs.smart_home_key = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_newline_strip"); editor_prefs.newline_strip = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_auto_multiline"); editor_prefs.auto_continue_multiline = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_symbol_auto_completion"); editor_prefs.auto_complete_symbols = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "spin_symbol_complete_chars"); gtk_spin_button_update(GTK_SPIN_BUTTON(widget)); editor_prefs.symbolcompletion_min_chars = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget)); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "spin_symbollistheight"); gtk_spin_button_update(GTK_SPIN_BUTTON(widget)); editor_prefs.symbolcompletion_max_height = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget)); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "spin_line_break"); gtk_spin_button_update(GTK_SPIN_BUTTON(widget)); editor_prefs.line_break_column = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget)); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_autoclose_parenthesis"); autoclose_brackets[0] = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_autoclose_cbracket"); autoclose_brackets[1] = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_autoclose_sbracket"); autoclose_brackets[2] = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_autoclose_squote"); autoclose_brackets[3] = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_autoclose_dquote"); autoclose_brackets[4] = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); editor_prefs.autoclose_chars = (autoclose_brackets[0] ? GEANY_AC_PARENTHESIS : 0u) | (autoclose_brackets[1] ? GEANY_AC_CBRACKET : 0u) | (autoclose_brackets[2] ? GEANY_AC_SBRACKET : 0u) | (autoclose_brackets[3] ? GEANY_AC_SQUOTE : 0u) | (autoclose_brackets[4] ? GEANY_AC_DQUOTE : 0u); /* Tools Settings */ widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_com_term"); g_free(tool_prefs.term_cmd); tool_prefs.term_cmd = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget))); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_browser"); g_free(tool_prefs.browser_cmd); tool_prefs.browser_cmd = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget))); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_grep"); g_free(tool_prefs.grep_cmd); tool_prefs.grep_cmd = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget))); /* Template settings */ widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_developer"); g_free(template_prefs.developer); template_prefs.developer = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget))); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_company"); g_free(template_prefs.company); template_prefs.company = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget))); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_mail"); g_free(template_prefs.mail); template_prefs.mail = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget))); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_initial"); g_free(template_prefs.initials); template_prefs.initials = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget))); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_version"); g_free(template_prefs.version); template_prefs.version = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget))); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_year"); g_free(template_prefs.year_format); template_prefs.year_format = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget))); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_date"); g_free(template_prefs.date_format); template_prefs.date_format = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget))); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_datetime"); g_free(template_prefs.datetime_format); template_prefs.datetime_format = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget))); /* Keybindings */ if (global_kb_data.edited) { kb_update(&global_kb_data); tools_create_insert_custom_command_menu_items(); keybindings_write_to_file(); #ifdef MAC_INTEGRATION /* Force re-syncing the menubar to update displayed keybindings. */ gtkosx_application_sync_menubar(gtkosx_application_get()); #endif } /* Printing */ widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_print_gtk"); printing_prefs.use_gtk_printing = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_print_external_cmd"); g_free(printing_prefs.external_print_cmd); printing_prefs.external_print_cmd = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget))); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_print_linenumbers"); printing_prefs.print_line_numbers = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_print_pagenumbers"); printing_prefs.print_page_numbers = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_print_pageheader"); printing_prefs.print_page_header = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_print_basename"); printing_prefs.page_header_basename = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_print_dateformat"); g_free(printing_prefs.page_header_datefmt); printing_prefs.page_header_datefmt = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget))); #ifdef HAVE_VTE widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_vte"); vte_info.load_vte = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); /* VTE settings */ if (vte_info.have_vte) { VteConfig *vc = &vte_config; widget = ui_lookup_widget(ui_widgets.prefs_dialog, "spin_scrollback"); gtk_spin_button_update(GTK_SPIN_BUTTON(widget)); vc->scrollback_lines = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget)); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_shell"); g_free(vc->shell); vc->shell = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget))); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_scroll_key"); vc->scroll_on_key = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_scroll_out"); vc->scroll_on_out = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_enable_bash_keys"); vc->enable_bash_keys = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_ignore_menu_key"); vc->ignore_menu_bar_accel = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_follow_path"); vc->follow_path = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_run_in_vte"); vc->run_in_vte = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_skip_script"); vc->skip_run_script = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_cursor_blinks"); vc->cursor_blinks = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); vte_apply_user_settings(); } #endif /* apply the changes made */ ui_statusbar_showhide(interface_prefs.statusbar_visible); sidebar_openfiles_update_all(); /* to update if full path setting has changed */ toolbar_apply_settings(); toolbar_update_ui(); toolbar_show_hide(); ui_sidebar_show_hide(); gtk_notebook_set_show_tabs(GTK_NOTEBOOK(main_widgets.notebook), interface_prefs.show_notebook_tabs); gtk_notebook_set_tab_pos(GTK_NOTEBOOK(main_widgets.notebook), interface_prefs.tab_pos_editor); gtk_notebook_set_tab_pos(GTK_NOTEBOOK(msgwindow.notebook), interface_prefs.tab_pos_msgwin); gtk_notebook_set_tab_pos(GTK_NOTEBOOK(main_widgets.sidebar_notebook), interface_prefs.tab_pos_sidebar); /* re-colourise all open documents, if tab width or long line settings have changed */ for (i = 0; i < documents_array->len; i++) { if (documents[i]->is_valid) { editor_apply_update_prefs(documents[i]->editor); if (! editor_prefs.folding) editor_unfold_all(documents[i]->editor); document_update_tab_label(documents[i]); } } ui_document_show_hide(NULL); ui_update_view_editor_menu_items(); /* various preferences */ ui_save_buttons_toggle((doc != NULL) ? doc->changed : FALSE); msgwin_show_hide_tabs(); ui_update_statusbar(doc, -1); ui_set_window_title(doc); /* store all settings */ configuration_save(); } if (response == GTK_RESPONSE_HELP) { open_preferences_help(); } else if (response != GTK_RESPONSE_APPLY) { gtk_tree_store_clear(global_kb_data.store); gtk_widget_hide(GTK_WIDGET(dialog)); } } static void on_color_button_choose_cb(GtkColorButton *widget, gpointer user_data) { GdkColor color; gtk_color_button_get_color(widget, &color); SETPTR(editor_prefs.long_line_color, utils_get_hex_from_color(&color)); } static void on_prefs_font_choosed(GtkFontButton *widget, gpointer user_data) { const gchar *fontbtn = gtk_font_button_get_font_name(widget); guint i; switch (GPOINTER_TO_INT(user_data)) { case 1: { if (strcmp(fontbtn, interface_prefs.tagbar_font) == 0) break; SETPTR(interface_prefs.tagbar_font, g_strdup(fontbtn)); for (i = 0; i < documents_array->len; i++) { GeanyDocument *doc = documents[i]; if (documents[i]->is_valid && GTK_IS_WIDGET(doc->priv->tag_tree)) ui_widget_modify_font_from_string(doc->priv->tag_tree, interface_prefs.tagbar_font); } if (GTK_IS_WIDGET(tv.default_tag_tree)) ui_widget_modify_font_from_string(tv.default_tag_tree, interface_prefs.tagbar_font); ui_widget_modify_font_from_string(tv.tree_openfiles, interface_prefs.tagbar_font); break; } case 2: { if (strcmp(fontbtn, interface_prefs.msgwin_font) == 0) break; SETPTR(interface_prefs.msgwin_font, g_strdup(fontbtn)); ui_widget_modify_font_from_string(msgwindow.tree_compiler, interface_prefs.msgwin_font); ui_widget_modify_font_from_string(msgwindow.tree_msg, interface_prefs.msgwin_font); ui_widget_modify_font_from_string(msgwindow.tree_status, interface_prefs.msgwin_font); ui_widget_modify_font_from_string(msgwindow.scribble, interface_prefs.msgwin_font); break; } case 3: { ui_set_editor_font(fontbtn); break; } } } static void kb_change_iter_shortcut(KbData *kbdata, GtkTreeIter *iter, const gchar *new_text) { guint lkey; GdkModifierType lmods; gtk_accelerator_parse(new_text, &lkey, &lmods); if (kb_find_duplicate(kbdata->store, ui_widgets.prefs_dialog, iter, lkey, lmods, new_text)) return; /* set the values here, because of the above check, setting it in * gtk_accelerator_parse would return a wrong key combination if it is duplicate */ kb_set_shortcut(kbdata->store, iter, lkey, lmods); kbdata->edited = TRUE; } static void kb_cell_edited_cb(GtkCellRendererText *cellrenderertext, gchar *path, gchar *new_text, KbData *kbdata) { if (path != NULL && new_text != NULL) { GtkTreeIter iter; gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(kbdata->store), &iter, path); if (gtk_tree_model_iter_has_child(GTK_TREE_MODEL(kbdata->store), &iter)) return; /* ignore group items */ kb_change_iter_shortcut(kbdata, &iter, new_text); } } static gboolean kb_grab_key_dialog_key_press_cb(GtkWidget *dialog, GdkEventKey *event, GtkLabel *label) { gchar *str; guint state; g_return_val_if_fail(GTK_IS_LABEL(label), FALSE); state = keybindings_get_modifiers(event->state); if (event->keyval == GDK_KEY_Escape) return FALSE; /* close the dialog, don't allow escape when detecting keybindings. */ str = gtk_accelerator_name(event->keyval, state); gtk_label_set_text(label, str); g_free(str); return TRUE; } /* test if the entered key combination is already used * returns true if cancelling duplicate */ static gboolean kb_find_duplicate(GtkTreeStore *store, GtkWidget *parent, GtkTreeIter *old_iter, guint key, GdkModifierType mods, const gchar *shortcut) { GtkTreeModel *model = GTK_TREE_MODEL(store); GtkTreeIter parent_iter; gchar *kb_str; guint kb_key; GdkModifierType kb_mods; /* allow duplicate if there is no key combination */ if (key == 0 && mods == 0) return FALSE; /* don't check if the new keybinding is the same as the old one */ gtk_tree_model_get(model, old_iter, KB_TREE_SHORTCUT, &kb_str, -1); if (kb_str) { gtk_accelerator_parse(kb_str, &kb_key, &kb_mods); g_free(kb_str); if (key == kb_key && mods == kb_mods) return FALSE; } if (! gtk_tree_model_get_iter_first(model, &parent_iter)) return FALSE; do /* foreach top level */ { GtkTreeIter iter; if (! gtk_tree_model_iter_children(model, &iter, &parent_iter)) continue; do /* foreach children */ { gtk_tree_model_get(model, &iter, KB_TREE_SHORTCUT, &kb_str, -1); if (! kb_str) continue; gtk_accelerator_parse(kb_str, &kb_key, &kb_mods); g_free(kb_str); /* search another item with the same key and modifiers */ if (kb_key == key && kb_mods == mods) { gchar *label; gint ret; gtk_tree_model_get(model, &iter, KB_TREE_ACTION, &label, -1); ret = dialogs_show_prompt(parent, _("_Allow"), GTK_RESPONSE_APPLY, GTK_STOCK_CANCEL, GTK_RESPONSE_NO, _("_Override"), GTK_RESPONSE_YES, _("Override that keybinding?"), _("The combination '%s' is already used for \"%s\"."), shortcut, label); g_free(label); if (ret == GTK_RESPONSE_YES) { kb_set_shortcut(store, &iter, 0, 0); /* clear shortcut */ /* carry on looking for other duplicates if overriding */ continue; } return ret != GTK_RESPONSE_APPLY; } } while (gtk_tree_model_iter_next(model, &iter)); } while (gtk_tree_model_iter_next(model, &parent_iter)); return FALSE; } static void on_toolbar_show_toggled(GtkToggleButton *togglebutton, gpointer user_data) { gboolean sens = gtk_toggle_button_get_active(togglebutton); gtk_widget_set_sensitive( ui_lookup_widget(ui_widgets.prefs_dialog, "frame_toolbar_style"), sens); gtk_widget_set_sensitive( ui_lookup_widget(ui_widgets.prefs_dialog, "frame_toolbar_icon"), sens); gtk_widget_set_sensitive( ui_lookup_widget(ui_widgets.prefs_dialog, "button_customize_toolbar"), sens); gtk_widget_set_sensitive( ui_lookup_widget(ui_widgets.prefs_dialog, "check_toolbar_in_menu"), sens); } static void on_show_notebook_tabs_toggled(GtkToggleButton *togglebutton, gpointer user_data) { gboolean sens = gtk_toggle_button_get_active(togglebutton); /* tab placement only enabled when tabs are visible */ gtk_widget_set_sensitive(ui_lookup_widget(ui_widgets.prefs_dialog, "combo_tab_editor"), sens); gtk_widget_set_sensitive(ui_lookup_widget(ui_widgets.prefs_dialog, "check_show_tab_cross"), sens); } static void on_use_folding_toggled(GtkToggleButton *togglebutton, gpointer user_data) { gboolean sens = gtk_toggle_button_get_active(togglebutton); gtk_widget_set_sensitive(ui_lookup_widget(ui_widgets.prefs_dialog, "check_unfold_children"), sens); } static void on_check_line_end_toggled(GtkToggleButton *togglebutton, gpointer user_data) { gboolean sens = gtk_toggle_button_get_active(togglebutton); gtk_widget_set_sensitive(ui_lookup_widget(ui_widgets.prefs_dialog, "check_line_endings_only_when_differ"), sens); } static void on_enable_plugins_toggled(GtkToggleButton *togglebutton, gpointer user_data) { gboolean sens = gtk_toggle_button_get_active(togglebutton); gtk_widget_set_sensitive(ui_lookup_widget(ui_widgets.prefs_dialog, "extra_plugin_path_entry"), sens); gtk_widget_set_sensitive(ui_lookup_widget(ui_widgets.prefs_dialog, "extra_plugin_path_button"), sens); } static void on_open_encoding_toggled(GtkToggleButton *togglebutton, gpointer user_data) { gboolean sens = gtk_toggle_button_get_active(togglebutton); gtk_widget_set_sensitive(ui_lookup_widget(ui_widgets.prefs_dialog, "eventbox3"), sens); gtk_widget_set_sensitive(ui_lookup_widget(ui_widgets.prefs_dialog, "label_open_encoding"), sens); } static void on_sidebar_visible_toggled(GtkToggleButton *togglebutton, gpointer user_data) { gboolean sens = gtk_toggle_button_get_active(togglebutton); gtk_widget_set_sensitive(ui_lookup_widget(ui_widgets.prefs_dialog, "box_sidebar_visible_children"), sens); } static void on_prefs_print_radio_button_toggled(GtkToggleButton *togglebutton, gpointer user_data) { gboolean sens = gtk_toggle_button_get_active(togglebutton); gtk_widget_set_sensitive(ui_lookup_widget(ui_widgets.prefs_dialog, "vbox29"), sens); gtk_widget_set_sensitive(ui_lookup_widget(ui_widgets.prefs_dialog, "hbox9"), ! sens); } static void on_prefs_print_page_header_toggled(GtkToggleButton *togglebutton, gpointer user_data) { gboolean sens = gtk_toggle_button_get_active(togglebutton); gtk_widget_set_sensitive(ui_lookup_widget(ui_widgets.prefs_dialog, "check_print_basename"), sens); gtk_widget_set_sensitive(ui_lookup_widget(ui_widgets.prefs_dialog, "entry_print_dateformat"), sens); } static void open_preferences_help(void) { gchar *uri; const gchar *label, *suffix = NULL; GtkNotebook *notebook = GTK_NOTEBOOK( ui_lookup_widget(ui_widgets.prefs_dialog, "notebook2")); gint page_nr = gtk_notebook_get_current_page(notebook); GtkWidget *page = gtk_notebook_get_nth_page(notebook, page_nr); label = gtk_notebook_get_tab_label_text(notebook, page); /* TODO Find a better way to map the current notebook page to the * corresponding chapter in the documentation, comparing translatable * strings is easy to break. Maybe attach an identifying string to the * tab label object. */ if (utils_str_equal(label, _("General"))) suffix = "#general-startup-preferences"; else if (utils_str_equal(label, _("Interface"))) suffix = "#interface-preferences"; else if (utils_str_equal(label, _("Toolbar"))) suffix = "#toolbar-preferences"; else if (utils_str_equal(label, _("Editor"))) suffix = "#editor-features-preferences"; else if (utils_str_equal(label, _("Files"))) suffix = "#files-preferences"; else if (utils_str_equal(label, _("Tools"))) suffix = "#tools-preferences"; else if (utils_str_equal(label, _("Templates"))) suffix = "#template-preferences"; else if (utils_str_equal(label, _("Keybindings"))) suffix = "#keybinding-preferences"; else if (utils_str_equal(label, _("Printing"))) suffix = "#printing-preferences"; else if (utils_str_equal(label, _("Various"))) suffix = "#various-preferences"; else if (utils_str_equal(label, _("Terminal"))) suffix = "#terminal-vte-preferences"; uri = utils_get_help_url(suffix); utils_open_browser(uri); g_free(uri); } static gboolean prefs_dialog_key_press_response_cb(GtkWidget *dialog, GdkEventKey *event, gpointer data) { GeanyKeyBinding *kb = keybindings_lookup_item(GEANY_KEY_GROUP_HELP, GEANY_KEYS_HELP_HELP); if (keybindings_check_event(event, kb)) { open_preferences_help(); return TRUE; } return FALSE; } static void list_store_append_text(GtkListStore *list, const gchar *text) { GtkTreeIter iter; gtk_list_store_append(list, &iter); gtk_list_store_set(list, &iter, 0, text, -1); } void prefs_show_dialog(void) { if (ui_widgets.prefs_dialog == NULL) { GtkListStore *eol_list; GtkWidget *label; ui_widgets.prefs_dialog = create_prefs_dialog(); gtk_widget_set_name(ui_widgets.prefs_dialog, "GeanyPrefsDialog"); gtk_window_set_transient_for(GTK_WINDOW(ui_widgets.prefs_dialog), GTK_WINDOW(main_widgets.window)); /* init the file encoding combo boxes */ { struct { const gchar *combo, *renderer; } names[] = { { "combo_new_encoding", "combo_new_encoding_renderer" }, { "combo_open_encoding", "combo_open_encoding_renderer" } }; guint i; GtkTreeStore *encoding_list = encodings_encoding_store_new(FALSE); for (i = 0; i < G_N_ELEMENTS(names); i++) { GtkWidget *combo = ui_lookup_widget(ui_widgets.prefs_dialog, names[i].combo); gtk_cell_layout_set_cell_data_func(GTK_CELL_LAYOUT(combo), ui_builder_get_object(names[i].renderer), encodings_encoding_store_cell_data_func, NULL, NULL); gtk_combo_box_set_model(GTK_COMBO_BOX(combo), GTK_TREE_MODEL(encoding_list)); } g_object_unref(encoding_list); } /* init the eol character combo box */ eol_list = ui_builder_get_object("eol_list"); list_store_append_text(eol_list, utils_get_eol_name(SC_EOL_CRLF)); list_store_append_text(eol_list, utils_get_eol_name(SC_EOL_CR)); list_store_append_text(eol_list, utils_get_eol_name(SC_EOL_LF)); /* add manually GeanyWrapLabels because they can't be added with Glade */ /* page Tools */ label = geany_wrap_label_new(_("Enter tool paths below. Tools you do not need can be left blank.")); gtk_widget_show(label); gtk_box_pack_start(GTK_BOX(ui_lookup_widget(ui_widgets.prefs_dialog, "vbox33")), label, FALSE, TRUE, 5); /* page Templates */ label = geany_wrap_label_new(_("Set the information to be used in templates. See the documentation for details.")); gtk_widget_show(label); gtk_box_pack_start(GTK_BOX(ui_lookup_widget(ui_widgets.prefs_dialog, "vbox31")), label, FALSE, TRUE, 5); /* page Keybindings */ label = geany_wrap_label_new(_("Here you can change keyboard shortcuts for various actions. Select one and press the Change button to enter a new shortcut, or double click on an action to edit the string representation of the shortcut directly.")); gtk_widget_show(label); gtk_box_pack_start(GTK_BOX(ui_lookup_widget(ui_widgets.prefs_dialog, "vbox32")), label, FALSE, TRUE, 5); /* page Editor->Indentation */ label = geany_wrap_label_new(_("Warning: these settings are overridden by the current project. See Project->Properties.")); gtk_widget_show(label); gtk_label_set_use_markup(GTK_LABEL(label), TRUE); gtk_misc_set_padding(GTK_MISC(label), 6, 0); gtk_box_pack_start(GTK_BOX(ui_lookup_widget(ui_widgets.prefs_dialog, "label_project_indent_warning")), label, FALSE, TRUE, 5); /* add the clear icon to GtkEntry widgets in the dialog */ { const gchar *names[] = { "startup_path_entry", "project_file_path_entry", "extra_plugin_path_entry", "entry_toggle_mark", /* "entry_com_make", */ "entry_com_term", "entry_browser", "entry_grep", "entry_contextaction", "entry_template_developer", "entry_template_initial", "entry_template_mail", "entry_template_company", "entry_template_version", "entry_template_year", "entry_template_date", "entry_template_datetime", "entry_print_external_cmd", "entry_print_dateformat"}; const gchar **name; foreach_c_array(name, names, G_N_ELEMENTS(names)) ui_entry_add_clear_icon(GTK_ENTRY(ui_lookup_widget(ui_widgets.prefs_dialog, *name))); } /* page Various */ various_treeview = GTK_TREE_VIEW(ui_lookup_widget(ui_widgets.prefs_dialog, "various_treeview")); stash_tree_setup(pref_groups, various_treeview); #ifdef HAVE_VTE vte_append_preferences_tab(); #endif #ifndef G_OS_WIN32 gtk_widget_hide(ui_lookup_widget(ui_widgets.prefs_dialog, "check_native_windows_dialogs")); #endif ui_setup_open_button_callback(ui_lookup_widget(ui_widgets.prefs_dialog, "startup_path_button"), NULL, GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, GTK_ENTRY(ui_lookup_widget(ui_widgets.prefs_dialog, "startup_path_entry"))); ui_setup_open_button_callback(ui_lookup_widget(ui_widgets.prefs_dialog, "extra_plugin_path_button"), NULL, GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, GTK_ENTRY(ui_lookup_widget(ui_widgets.prefs_dialog, "extra_plugin_path_entry"))); g_signal_connect(ui_widgets.prefs_dialog, "response", G_CALLBACK(on_prefs_dialog_response), NULL); g_signal_connect(ui_widgets.prefs_dialog, "delete-event", G_CALLBACK(gtk_widget_hide_on_delete), NULL); g_signal_connect(ui_lookup_widget(ui_widgets.prefs_dialog, "tagbar_font"), "font-set", G_CALLBACK(on_prefs_font_choosed), GINT_TO_POINTER(1)); g_signal_connect(ui_lookup_widget(ui_widgets.prefs_dialog, "msgwin_font"), "font-set", G_CALLBACK(on_prefs_font_choosed), GINT_TO_POINTER(2)); g_signal_connect(ui_lookup_widget(ui_widgets.prefs_dialog, "editor_font"), "font-set", G_CALLBACK(on_prefs_font_choosed), GINT_TO_POINTER(3)); g_signal_connect(ui_lookup_widget(ui_widgets.prefs_dialog, "long_line_color"), "color-set", G_CALLBACK(on_color_button_choose_cb), NULL); /* file chooser buttons in the tools tab */ ui_setup_open_button_callback(ui_lookup_widget(ui_widgets.prefs_dialog, "button_term"), NULL, GTK_FILE_CHOOSER_ACTION_OPEN, GTK_ENTRY(ui_lookup_widget(ui_widgets.prefs_dialog, "entry_com_term"))); ui_setup_open_button_callback(ui_lookup_widget(ui_widgets.prefs_dialog, "button_browser"), NULL, GTK_FILE_CHOOSER_ACTION_OPEN, GTK_ENTRY(ui_lookup_widget(ui_widgets.prefs_dialog, "entry_browser"))); ui_setup_open_button_callback(ui_lookup_widget(ui_widgets.prefs_dialog, "button_grep"), NULL, GTK_FILE_CHOOSER_ACTION_OPEN, GTK_ENTRY(ui_lookup_widget(ui_widgets.prefs_dialog, "entry_grep"))); /* tools commands */ ui_setup_open_button_callback(ui_lookup_widget(ui_widgets.prefs_dialog, "button_contextaction"), NULL, GTK_FILE_CHOOSER_ACTION_OPEN, GTK_ENTRY(ui_lookup_widget(ui_widgets.prefs_dialog, "entry_contextaction"))); /* printing */ ui_setup_open_button_callback(ui_lookup_widget(ui_widgets.prefs_dialog, "button_print_external_cmd"), NULL, GTK_FILE_CHOOSER_ACTION_OPEN, GTK_ENTRY(ui_lookup_widget(ui_widgets.prefs_dialog, "entry_print_external_cmd"))); g_signal_connect(ui_lookup_widget(ui_widgets.prefs_dialog, "radio_print_gtk"), "toggled", G_CALLBACK(on_prefs_print_radio_button_toggled), NULL); g_signal_connect(ui_lookup_widget(ui_widgets.prefs_dialog, "check_print_pageheader"), "toggled", G_CALLBACK(on_prefs_print_page_header_toggled), NULL); g_signal_connect(ui_lookup_widget(ui_widgets.prefs_dialog, "check_plugins"), "toggled", G_CALLBACK(on_enable_plugins_toggled), NULL); g_signal_connect(ui_lookup_widget(ui_widgets.prefs_dialog, "check_toolbar_show"), "toggled", G_CALLBACK(on_toolbar_show_toggled), NULL); g_signal_connect(ui_lookup_widget(ui_widgets.prefs_dialog, "check_show_notebook_tabs"), "toggled", G_CALLBACK(on_show_notebook_tabs_toggled), NULL); g_signal_connect(ui_lookup_widget(ui_widgets.prefs_dialog, "check_folding"), "toggled", G_CALLBACK(on_use_folding_toggled), NULL); g_signal_connect(ui_lookup_widget(ui_widgets.prefs_dialog, "check_line_end"), "toggled", G_CALLBACK(on_check_line_end_toggled), NULL); g_signal_connect(ui_lookup_widget(ui_widgets.prefs_dialog, "check_open_encoding"), "toggled", G_CALLBACK(on_open_encoding_toggled), NULL); g_signal_connect(ui_lookup_widget(ui_widgets.prefs_dialog, "check_sidebar_visible"), "toggled", G_CALLBACK(on_sidebar_visible_toggled), NULL); g_signal_connect(ui_widgets.prefs_dialog, "key-press-event", G_CALLBACK(prefs_dialog_key_press_response_cb), NULL); } prefs_init_dialog(); gtk_window_present(GTK_WINDOW(ui_widgets.prefs_dialog)); } geany-2.0/src/tagmanager/0000755000175000017500000000000014514253233012356 500000000000000geany-2.0/src/tagmanager/tm_ctags.c0000644000175000017500000003341314514252267014255 00000000000000/* * Copyright (c) 2016, Jiri Techet * * This source code is released for free distribution under the terms of the * GNU General Public License version 2 or (at your option) any later version. * * Encapsulates ctags so it is isolated from the rest of Geany. */ #include "tm_ctags.h" #include "tm_tag.h" #include "general.h" /* must always come before the rest of ctags headers */ #include "entry_p.h" #include "error_p.h" #include "field_p.h" #include "options_p.h" #include "parse_p.h" #include "trashbox_p.h" #include "writer_p.h" #include "xtag_p.h" #include "param_p.h" #include static gint write_entry(tagWriter *writer, MIO * mio, const tagEntryInfo *const tag, void *user_data); static void rescan_failed(tagWriter *writer, gulong valid_tag_num, void *user_data); tagWriter geanyWriter = { .writeEntry = write_entry, .writePtagEntry = NULL, /* no pseudo-tags */ .preWriteEntry = NULL, .postWriteEntry = NULL, .rescanFailedEntry = rescan_failed, .treatFieldAsFixed = NULL, .defaultFileName = "geany_tags_file_which_should_never_appear_anywhere", .private = NULL, .type = WRITER_CUSTOM }; static bool nonfatal_error_printer(const errorSelection selection, const gchar *const format, va_list ap, void *data CTAGS_ATTR_UNUSED) { g_logv(G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, format, ap); return false; } static void enable_roles(const TMParserType lang, guint kind) { unsigned int c = countLanguageRoles(lang, kind); kindDefinition *def = getLanguageKind(lang, kind); gchar kind_letter = def->letter; for (unsigned int i = 0; i < c; i++) { roleDefinition* rdef = getLanguageRole(lang, kind, (int)i); gboolean should_enable = tm_parser_enable_role(lang, kind_letter); enableRole(rdef, should_enable); } } static void enable_kinds_and_roles(void) { TMParserType lang; for (lang = 0; lang < (gint)countParsers(); lang++) { guint kind_num = countLanguageKinds(lang); guint kind; for (kind = 0; kind < kind_num; kind++) { kindDefinition *def = getLanguageKind(lang, kind); gboolean should_enable = tm_parser_enable_kind(lang, def->letter); enableKind(def, should_enable); if (should_enable) enable_roles(lang, kind); } } } /* Initializes a TMTag structure with information from a ctagsTag struct used by the ctags parsers. Note that the TMTag structure must be malloc()ed before calling this function. @param tag The TMTag structure to initialize @param file Pointer to a TMSourceFile struct (it is assigned to the file member) @param tag_entry Tag information gathered by the ctags parser @return TRUE on success, FALSE on failure */ static gboolean init_tag(TMTag *tag, TMSourceFile *file, const tagEntryInfo *tag_entry) { TMTagType type; guchar kind_letter; TMParserType lang; if (!tag_entry) return FALSE; lang = tag_entry->langType; kind_letter = getLanguageKind(tag_entry->langType, tag_entry->kindIndex)->letter; type = tm_parser_get_tag_type(kind_letter, lang); if (file->lang != lang) /* this is a tag from a subparser */ { /* check for possible re-definition of subparser type */ type = tm_parser_get_subparser_type(file->lang, lang, type); } if (!tag_entry->name || type == tm_tag_undef_t) return FALSE; tag->name = g_strdup(tag_entry->name); tag->type = type; tag->local = tag_entry->isFileScope && file->trust_file_scope; tag->flags = tm_tag_flag_none_t; if (isTagExtraBitMarked(tag_entry, XTAG_ANONYMOUS)) tag->flags |= tm_tag_flag_anon_t; tag->kind_letter = kind_letter; tag->line = tag_entry->lineNumber; if (NULL != tag_entry->extensionFields.signature) tag->arglist = g_strdup(tag_entry->extensionFields.signature); if ((NULL != tag_entry->extensionFields.scopeName) && (0 != tag_entry->extensionFields.scopeName[0])) tag->scope = g_strdup(tag_entry->extensionFields.scopeName); if (tag_entry->extensionFields.inheritance != NULL) tag->inheritance = g_strdup(tag_entry->extensionFields.inheritance); if (tag_entry->extensionFields.typeRef[1] != NULL) tag->var_type = g_strdup(tag_entry->extensionFields.typeRef[1]); if (tag_entry->extensionFields.access != NULL) tag->access = tm_source_file_get_tag_access(tag_entry->extensionFields.access); if (tag_entry->extensionFields.implementation != NULL) tag->impl = tm_source_file_get_tag_impl(tag_entry->extensionFields.implementation); if ((tm_tag_macro_t == tag->type) && (NULL != tag->arglist)) tag->type = tm_tag_macro_with_arg_t; tag->file = file; /* redefine lang also for subparsers because the rest of Geany assumes that * tags from a single file are from a single language */ tag->lang = file->lang; if (tag->scope) { gchar *new_scope = tm_parser_update_scope(tag->lang, tag->scope); if (new_scope != tag->scope) { g_free(tag->scope); tag->scope = new_scope; } } return TRUE; } static gint write_entry(tagWriter *writer, MIO * mio, const tagEntryInfo *const tag, void *user_data) { TMSourceFile *source_file = user_data; TMTag *tm_tag = tm_tag_new(); getTagScopeInformation((tagEntryInfo *)tag, NULL, NULL); if (!init_tag(tm_tag, source_file, tag)) { tm_tag_unref(tm_tag); return 0; } g_ptr_array_add(source_file->tags_array, tm_tag); /* output length - we don't write anything to the MIO */ return 0; } static void rescan_failed(tagWriter *writer, gulong valid_tag_num, void *user_data) { TMSourceFile *source_file = user_data; GPtrArray *tags_array = source_file->tags_array; if (tags_array->len > valid_tag_num) { guint i; for (i = valid_tag_num; i < tags_array->len; i++) tm_tag_unref(tags_array->pdata[i]); g_ptr_array_set_size(tags_array, valid_tag_num); } } /* keep in sync with ctags main() - use only things interesting for us */ void tm_ctags_init(void) { initDefaultTrashBox(); setErrorPrinter(nonfatal_error_printer, NULL); setTagWriter(WRITER_CUSTOM, &geanyWriter); checkRegex(); initFieldObjects(); initXtagObjects(); initializeParsing(); initOptions(); initRegexOptscript(); /* make sure all parsers are initialized */ initializeParser(LANG_AUTO); /* change default values which are false */ enableXtag(XTAG_TAGS_GENERATED_BY_GUEST_PARSERS, true); enableXtag(XTAG_REFERENCE_TAGS, true); /* some kinds we are interested in are disabled by default */ enable_kinds_and_roles(); } void tm_ctags_add_ignore_symbol(const char *value) { langType lang = getNamedLanguage ("CPreProcessor", 0); gchar *val = g_strdup(value); /* make sure we don't enter empty string - passing NULL or "" clears * the ignore list in ctags */ val = g_strstrip(val); if (*val) applyParameter (lang, "ignore", val); g_free(val); } void tm_ctags_clear_ignore_symbols(void) { langType lang = getNamedLanguage ("CPreProcessor", 0); applyParameter (lang, "ignore", NULL); } /* call after all tags have been collected so we don't have to handle reparses * with the counter (which gets complicated when also subparsers are involved) */ static void rename_anon_tags(TMSourceFile *source_file) { gboolean is_c = source_file->lang == TM_PARSER_C || source_file->lang == TM_PARSER_CPP; gint *anon_counter_table = NULL; GPtrArray *removed_typedefs = NULL; guint i; for (i = 0; i < source_file->tags_array->len; i++) { TMTag *tag = TM_TAG(source_file->tags_array->pdata[i]); if (tm_tag_is_anon(tag)) { gchar *orig_name, *new_name = NULL; guint j; guint new_name_len, orig_name_len; gboolean inside_nesting = FALSE; guint scope_len = tag->scope ? strlen(tag->scope) : 0; gchar kind = tag->kind_letter; orig_name = tag->name; orig_name_len = strlen(orig_name); if (is_c) { /* First check if there's a typedef behind the scope nesting * such as typedef struct {} Foo; - in this case we can replace * the anon tag with Foo */ for (j = i + 1; j < source_file->tags_array->len; j++) { TMTag *nested_tag = TM_TAG(source_file->tags_array->pdata[j]); guint nested_scope_len = nested_tag->scope ? strlen(nested_tag->scope) : 0; /* Tags can be interleaved with scopeless macros - skip those */ if (nested_tag->type & (tm_tag_macro_t | tm_tag_macro_with_arg_t)) continue; /* Nested tags have longer scope than the parent - once the scope * is equal or lower than the parent scope, we are outside the tag's * scope. */ if (nested_scope_len <= scope_len) break; } /* We are out of the nesting - the next tag could be a typedef */ if (j < source_file->tags_array->len) { TMTag *typedef_tag = TM_TAG(source_file->tags_array->pdata[j]); guint typedef_scope_len = typedef_tag->scope ? strlen(typedef_tag->scope) : 0; /* Should be at the same scope level as the anon tag */ if (typedef_tag->type == tm_tag_typedef_t && typedef_scope_len == scope_len && g_strcmp0(typedef_tag->var_type, tag->name) == 0) { /* set the name of the original anon tag and pretend * it wasn't a anon tag */ tag->name = g_strdup(typedef_tag->name); tag->flags &= ~tm_tag_flag_anon_t; new_name = tag->name; /* the typedef tag will be removed */ if (!removed_typedefs) removed_typedefs = g_ptr_array_new(); g_ptr_array_add(removed_typedefs, GUINT_TO_POINTER(j)); } } } /* there's no typedef name for the anon tag so let's generate one */ if (!new_name) { gchar buf[50]; guint anon_counter; const gchar *kind_name = tm_ctags_get_kind_name(kind, tag->lang); if (!anon_counter_table) anon_counter_table = g_new0(gint, 256); anon_counter = ++anon_counter_table[kind]; sprintf(buf, "anon_%s_%u", kind_name, anon_counter); tag->name = g_strdup(buf); new_name = tag->name; } new_name_len = strlen(new_name); /* Check if this tag is parent of some other tag - if so, we have to * update the scope. It can only be parent of the following tags * so start with the next tag. */ for (j = i + 1; j < source_file->tags_array->len; j++) { TMTag *nested_tag = TM_TAG(source_file->tags_array->pdata[j]); guint nested_scope_len = nested_tag->scope ? strlen(nested_tag->scope) : 0; gchar *pos; /* Tags can be interleaved with scopeless macros - skip those */ if (is_c && nested_tag->type & (tm_tag_macro_t | tm_tag_macro_with_arg_t)) continue; /* In Fortran, we can create variables of anonymous structures: * structure var1, var2 * integer a * end structure * and the parser first generates tags for var1 and var2 which * are on the same scope as the structure itself. So first * we need to skip past the tags on the same scope and only * afterwards we get the nested tags. * */ if (source_file->lang == TM_PARSER_FORTRAN && !inside_nesting && nested_scope_len == scope_len) continue; inside_nesting = TRUE; /* Terminate if outside of tag scope, see above */ if (nested_scope_len <= scope_len) break; pos = strstr(nested_tag->scope, orig_name); /* We found the parent name in the nested tag scope - replace it * with the new name. Note: anonymous tag names generated by * ctags are unique enough that we don't have to check for * scope separators here. */ if (pos) { gchar *str = g_malloc(nested_scope_len + 50); guint prefix_len = pos - nested_tag->scope; strncpy(str, nested_tag->scope, prefix_len); strcpy(str + prefix_len, new_name); strcpy(str + prefix_len + new_name_len, pos + orig_name_len); g_free(nested_tag->scope); nested_tag->scope = str; } } /* We are out of the nesting - the next tags could be variables * of an anonymous struct such as "struct {} a[2], *b, c;" */ while (j < source_file->tags_array->len) { TMTag *var_tag = TM_TAG(source_file->tags_array->pdata[j]); guint var_scope_len = var_tag->scope ? strlen(var_tag->scope) : 0; gchar *pos; /* Should be at the same scope level as the anon tag */ if (var_scope_len == scope_len && var_tag->var_type && (pos = strstr(var_tag->var_type, orig_name))) { GString *str = g_string_new(var_tag->var_type); gssize p = pos - var_tag->var_type; g_string_erase(str, p, strlen(orig_name)); g_string_insert(str, p, new_name); g_free(var_tag->var_type); var_tag->var_type = str->str; g_string_free(str, FALSE); } else break; j++; } g_free(orig_name); } } if (removed_typedefs) { for (i = 0; i < removed_typedefs->len; i++) { guint j = GPOINTER_TO_UINT(removed_typedefs->pdata[i]); TMTag *tag = TM_TAG(source_file->tags_array->pdata[j]); tm_tag_unref(tag); source_file->tags_array->pdata[j] = NULL; } /* remove NULL entries from the array */ tm_tags_prune(source_file->tags_array); g_ptr_array_free(removed_typedefs, TRUE); } if (anon_counter_table) g_free(anon_counter_table); } void tm_ctags_parse(guchar *buffer, gsize buffer_size, const gchar *file_name, TMParserType language, TMSourceFile *source_file) { g_return_if_fail(buffer != NULL || file_name != NULL); parseRawBuffer(file_name, buffer, buffer_size, language, source_file); rename_anon_tags(source_file); } const gchar *tm_ctags_get_lang_name(TMParserType lang) { return getLanguageName(lang); } TMParserType tm_ctags_get_named_lang(const gchar *name) { return getNamedLanguage(name, 0); } const gchar *tm_ctags_get_lang_kinds(TMParserType lang) { guint kind_num = countLanguageKinds(lang); static gchar kinds[257]; guint i; for (i = 0; i < kind_num; i++) kinds[i] = getLanguageKind(lang, i)->letter; kinds[i] = '\0'; return kinds; } const gchar *tm_ctags_get_kind_name(gchar kind, TMParserType lang) { kindDefinition *def = getLanguageKindForLetter(lang, kind); return def ? def->name : "unknown"; } gchar tm_ctags_get_kind_from_name(const gchar *name, TMParserType lang) { kindDefinition *def = getLanguageKindForName(lang, name); return def ? def->letter : '-'; } guint tm_ctags_get_lang_count(void) { return countParsers(); } geany-2.0/src/tagmanager/tm_parser.h0000644000175000017500000001116214514252267014452 00000000000000/* * * Copyright (c) 2014 The Geany contributors * * This source code is released for free distribution under the terms of the * GNU General Public License. * */ #ifndef TM_PARSER_H #define TM_PARSER_H #include G_BEGIN_DECLS /** Types of tags. It is a bitmask so that multiple tag types can be used simultaneously by 'OR'-ing them bitwise. e.g. tm_tag_class_t | tm_tag_struct_t */ typedef enum { tm_tag_undef_t = 0, /**< Unknown type */ tm_tag_class_t = 1, /**< Class declaration */ tm_tag_enum_t = 2, /**< Enum declaration */ tm_tag_enumerator_t = 4, /**< Enumerator value */ tm_tag_field_t = 8, /**< Field (Java only) */ tm_tag_function_t = 16, /**< Function definition */ tm_tag_interface_t = 32, /**< Interface (Java only) */ tm_tag_member_t = 64, /**< Member variable of class/struct */ tm_tag_method_t = 128, /**< Class method (Java only) */ tm_tag_namespace_t = 256, /**< Namespace declaration */ tm_tag_package_t = 512, /**< Package (Java only) */ tm_tag_prototype_t = 1024, /**< Function prototype */ tm_tag_struct_t = 2048, /**< Struct declaration */ tm_tag_typedef_t = 4096, /**< Typedef */ tm_tag_union_t = 8192, /**< Union */ tm_tag_variable_t = 16384, /**< Variable */ tm_tag_externvar_t = 32768, /**< Extern or forward declaration */ tm_tag_macro_t = 65536, /**< Macro (without arguments) */ tm_tag_macro_with_arg_t = 131072, /**< Parameterized macro */ tm_tag_local_var_t = 262144, /**< Local variable (inside function) */ tm_tag_other_t = 524288, /**< Other (non C/C++/Java tag) */ tm_tag_include_t = 1048576, /**< C/C++ included header file name */ tm_tag_max_t = 2097151 /**< Maximum value of TMTagType */ } TMTagType; /** @gironly * A integral type which can hold known parser type IDs **/ typedef gint TMParserType; #ifdef GEANY_PRIVATE /* keep in sync with tm_parsers.h and parser_map in tm_parser.c */ enum { TM_PARSER_NONE = -2, /* keep in sync with ctags LANG_IGNORE */ TM_PARSER_C = 0, TM_PARSER_CPP, TM_PARSER_JAVA, TM_PARSER_MAKEFILE, TM_PARSER_PASCAL, TM_PARSER_PERL, TM_PARSER_PHP, TM_PARSER_PYTHON, TM_PARSER_LATEX, TM_PARSER_ASM, TM_PARSER_CONF, TM_PARSER_SQL, TM_PARSER_DOCBOOK, TM_PARSER_ERLANG, TM_PARSER_CSS, TM_PARSER_RUBY, TM_PARSER_TCL, TM_PARSER_SH, TM_PARSER_D, TM_PARSER_FORTRAN, TM_PARSER_GDSCRIPT, TM_PARSER_DIFF, TM_PARSER_VHDL, TM_PARSER_LUA, TM_PARSER_JAVASCRIPT, TM_PARSER_HASKELL, TM_PARSER_CSHARP, TM_PARSER_FREEBASIC, TM_PARSER_HAXE, TM_PARSER_REST, TM_PARSER_HTML, TM_PARSER_ADA, TM_PARSER_CUDA, TM_PARSER_MATLAB, TM_PARSER_VALA, TM_PARSER_ACTIONSCRIPT, TM_PARSER_NSIS, TM_PARSER_MARKDOWN, TM_PARSER_TXT2TAGS, TM_PARSER_ABC, TM_PARSER_VERILOG, TM_PARSER_R, TM_PARSER_COBOL, TM_PARSER_OBJC, TM_PARSER_ASCIIDOC, TM_PARSER_ABAQUS, TM_PARSER_RUST, TM_PARSER_GO, TM_PARSER_JSON, TM_PARSER_ZEPHIR, TM_PARSER_POWERSHELL, TM_PARSER_JULIA, TM_PARSER_BIBTEX, TM_PARSER_CPREPROCESSOR, TM_PARSER_TCLOO, TM_PARSER_CLOJURE, TM_PARSER_LISP, TM_PARSER_TYPESCRIPT, TM_PARSER_BATCH, TM_PARSER_AUTOIT, TM_PARSER_COUNT }; /* keep in sync with icon names in symbols.c */ enum { TM_ICON_CLASS, TM_ICON_MACRO, TM_ICON_MEMBER, TM_ICON_METHOD, TM_ICON_NAMESPACE, TM_ICON_OTHER, TM_ICON_STRUCT, TM_ICON_VAR, TM_ICON_NONE, TM_N_ICONS = TM_ICON_NONE }; void tm_parser_verify_type_mappings(void); TMTagType tm_parser_get_tag_type(gchar kind, TMParserType lang); gchar tm_parser_get_tag_kind(TMTagType type, TMParserType lang); gint tm_parser_get_sidebar_group(TMParserType lang, TMTagType type); const gchar *tm_parser_get_sidebar_info(TMParserType lang, gint group, guint *icon); TMTagType tm_parser_get_subparser_type(TMParserType lang, TMParserType sublang, TMTagType type); gint tm_parser_scope_autocomplete_suffix(TMParserType lang, const gchar *str); const gchar *tm_parser_get_constructor_method(TMParserType lang); gboolean tm_parser_is_anon_name(TMParserType lang, const gchar *name); gchar *tm_parser_update_scope(TMParserType lang, gchar *scope); gboolean tm_parser_enable_role(TMParserType lang, gchar kind); gboolean tm_parser_enable_kind(TMParserType lang, gchar kind); gchar *tm_parser_format_variable(TMParserType lang, const gchar *name, const gchar *type, const gchar *scope); gchar *tm_parser_format_function(TMParserType lang, const gchar *fname, const gchar *args, const gchar *retval, const gchar *scope); const gchar *tm_parser_scope_separator(TMParserType lang); const gchar *tm_parser_scope_separator_printable(TMParserType lang); gboolean tm_parser_has_full_scope(TMParserType lang); gboolean tm_parser_langs_compatible(TMParserType lang, TMParserType other); #endif /* GEANY_PRIVATE */ G_END_DECLS #endif /* TM_PARSER_H */ geany-2.0/src/tagmanager/Makefile.am0000644000175000017500000000140014514252267014333 00000000000000AM_CPPFLAGS = \ -I$(srcdir) \ -I$(top_srcdir)/ctags/main \ -I$(top_srcdir)/ctags/libreadtags \ -I$(top_srcdir)/ctags/dsl \ -DGEANY_PRIVATE \ -DG_LOG_DOMAIN=\"Tagmanager\" if USE_BUNDLED_REGEX AM_CPPFLAGS += -I$(top_srcdir)/ctags/gnu_regex endif AM_CFLAGS = \ $(GTK_CFLAGS) \ @LIBGEANY_CFLAGS@ noinst_LTLIBRARIES = libtagmanager.la tagmanager_includedir = $(includedir)/geany/tagmanager tagmanager_include_HEADERS = \ tm_source_file.h \ tm_tag.h \ tm_workspace.h \ tm_parser.h libtagmanager_la_SOURCES = \ tm_ctags.h \ tm_ctags.c \ tm_parser.h \ tm_parser.c \ tm_parsers.h \ tm_source_file.h \ tm_source_file.c \ tm_tag.h \ tm_tag.c \ tm_workspace.h \ tm_workspace.c libtagmanager_la_LIBADD = $(top_builddir)/ctags/libctags.la $(GTK_LIBS) geany-2.0/src/tagmanager/tm_ctags.h0000644000175000017500000000204214514252267014254 00000000000000/* * Copyright (c) 2016, Jiri Techet * * This source code is released for free distribution under the terms of the * GNU General Public License version 2 or (at your option) any later version. * * Encapsulates ctags so it is isolated from the rest of Geany. */ #ifndef TM_CTAGS_H #define TM_CTAGS_H #include #include "tm_source_file.h" G_BEGIN_DECLS #ifdef GEANY_PRIVATE void tm_ctags_init(void); void tm_ctags_add_ignore_symbol(const char *value); void tm_ctags_clear_ignore_symbols(void); void tm_ctags_parse(guchar *buffer, gsize buffer_size, const gchar *file_name, TMParserType language, TMSourceFile *source_file); const gchar *tm_ctags_get_lang_name(TMParserType lang); TMParserType tm_ctags_get_named_lang(const gchar *name); const gchar *tm_ctags_get_lang_kinds(TMParserType lang); const gchar *tm_ctags_get_kind_name(gchar kind, TMParserType lang); gchar tm_ctags_get_kind_from_name(const gchar *name, TMParserType lang); guint tm_ctags_get_lang_count(void); #endif /* GEANY_PRIVATE */ G_END_DECLS #endif /* TM_CTAGS_H */ geany-2.0/src/tagmanager/tm_source_file.c0000644000175000017500000005047114514252267015456 00000000000000/* * * Copyright (c) 2001-2002, Biswapesh Chattopadhyay * Copyright 2005 The Geany contributors * * This source code is released for free distribution under the terms of the * GNU General Public License. * */ /** * @file tm_source_file.h The TMSourceFile structure and associated functions are used to maintain tags for individual files. */ #include #include #include #include #include #include #include #include #ifdef G_OS_WIN32 # define VC_EXTRALEAN # define WIN32_LEAN_AND_MEAN # include /* for GetFullPathName */ #endif #include "readtags.h" #include "tm_source_file.h" #include "tm_tag.h" #include "tm_parser.h" #include "tm_ctags.h" typedef struct { TMSourceFile public; guint refcount; } TMSourceFilePriv; typedef enum { TM_FILE_FORMAT_TAGMANAGER, TM_FILE_FORMAT_PIPE, TM_FILE_FORMAT_CTAGS } TMFileFormat; /* Note: To preserve binary compatibility, it is very important that you only *append* to this list ! */ enum { TA_NAME = 200, TA_LINE, TA_LOCAL, TA_POS, /* Obsolete */ TA_TYPE, TA_ARGLIST, TA_SCOPE, TA_VARTYPE, TA_INHERITS, TA_TIME, TA_ACCESS, TA_IMPL, TA_LANG, TA_INACTIVE, /* Obsolete */ TA_FLAGS }; #define SOURCE_FILE_NEW(S) ((S) = g_slice_new(TMSourceFilePriv)) #define SOURCE_FILE_FREE(S) g_slice_free(TMSourceFilePriv, (TMSourceFilePriv *) S) static int get_path_max(const char *path) { #ifdef PATH_MAX return PATH_MAX; #else int path_max = pathconf(path, _PC_PATH_MAX); if (path_max <= 0) path_max = 4096; return path_max; #endif } #if defined(G_OS_WIN32) && !defined(HAVE_REALPATH) /* realpath implementation for Windows found at https://bugzilla.gnome.org/show_bug.cgi?id=342926 * this one is better than e.g. liberty's lrealpath because this one uses Win32 API and works * with special chars within the filename */ static char *realpath (const char *pathname, char *resolved_path) { int size; if (resolved_path != NULL) { int path_max = get_path_max(pathname); size = GetFullPathNameA (pathname, path_max, resolved_path, NULL); if (size > path_max) return NULL; else return resolved_path; } else { size = GetFullPathNameA (pathname, 0, NULL, NULL); resolved_path = g_new0 (char, size); GetFullPathNameA (pathname, size, resolved_path, NULL); return resolved_path; } } #endif /** Given a file name, returns a newly allocated string containing the realpath() of the file. @param file_name The original file_name @return A newly allocated string containing the real path to the file. NULL if none is available. @deprecated since 1.32 (ABI 235) @see utils_get_real_path() */ GEANY_API_SYMBOL gchar *tm_get_real_path(const gchar *file_name) { if (file_name) { gsize len = get_path_max(file_name) + 1; gchar *path = g_malloc0(len); if (realpath(file_name, path)) return path; else g_free(path); } return NULL; } gchar tm_source_file_get_tag_impl(const gchar *impl) { if ((0 == strcmp("virtual", impl)) || (0 == strcmp("pure virtual", impl))) return TAG_IMPL_VIRTUAL; #ifdef TM_DEBUG g_warning("Unknown implementation %s", impl); #endif return TAG_IMPL_UNKNOWN; } gchar tm_source_file_get_tag_access(const gchar *access) { if (0 == strcmp("public", access)) return TAG_ACCESS_PUBLIC; else if (0 == strcmp("protected", access)) return TAG_ACCESS_PROTECTED; else if (0 == strcmp("private", access)) return TAG_ACCESS_PRIVATE; else if (0 == strcmp("friend", access)) return TAG_ACCESS_FRIEND; else if (0 == strcmp("default", access)) return TAG_ACCESS_DEFAULT; #ifdef TM_DEBUG g_warning("Unknown access type %s", access); #endif return TAG_ACCESS_UNKNOWN; } /* Initializes an already malloc()ed TMTag structure by reading a tag entry line from a file. The structure should be allocated beforehand. @param tag The TMTag structure to populate @param file The TMSourceFile struct (assigned to the file member) @param fp FILE pointer from where the tag line is read @return TRUE on success, FALSE on FAILURE */ static gboolean init_tag_from_file(TMTag *tag, TMSourceFile *file, FILE *fp, TMParserType lang) { guchar buf[BUFSIZ]; guchar *start, *end; gboolean status; guchar changed_char = TA_NAME; tag->refcount = 1; if ((NULL == fgets((gchar*)buf, BUFSIZ, fp)) || ('\0' == *buf)) return FALSE; for (start = end = buf, status = TRUE; (TRUE == status); start = end, ++ end) { while ((*end < TA_NAME) && (*end != '\0') && (*end != '\n')) ++ end; if (('\0' == *end) || ('\n' == *end)) status = FALSE; changed_char = *end; *end = '\0'; if (NULL == tag->name) { if (!isprint(*start)) return FALSE; else { tag->name = g_strdup((gchar*)start); if (tm_parser_is_anon_name(lang, tag->name)) tag->flags |= tm_tag_flag_anon_t; } } else { switch (*start) { case TA_LINE: tag->line = atol((gchar*)start + 1); break; case TA_LOCAL: tag->local = atoi((gchar*)start + 1); break; case TA_TYPE: tag->type = (TMTagType) atoi((gchar*)start + 1); break; case TA_ARGLIST: tag->arglist = g_strdup((gchar*)start + 1); break; case TA_SCOPE: tag->scope = g_strdup((gchar*)start + 1); break; case TA_FLAGS: tag->flags |= atoi((gchar*)start + 1); break; case TA_VARTYPE: tag->var_type = g_strdup((gchar*)start + 1); break; case TA_INHERITS: tag->inheritance = g_strdup((gchar*)start + 1); break; case TA_TIME: /* Obsolete */ break; case TA_LANG: /* Obsolete */ break; case TA_INACTIVE: /* Obsolete */ break; case TA_ACCESS: tag->access = (char) *(start + 1); break; case TA_IMPL: tag->impl = (char) *(start + 1); break; default: #ifdef GEANY_DEBUG g_warning("Unknown attribute %s", start + 1); #endif break; } } *end = changed_char; } if (NULL == tag->name) return FALSE; tag->file = file; return TRUE; } /* alternative parser for Pascal and LaTeX global tags files with the following format * tagname|return value|arglist|description\n */ static gboolean init_tag_from_file_alt(TMTag *tag, TMSourceFile *file, FILE *fp) { guchar buf[BUFSIZ]; guchar *start, *end; gboolean status; /*guchar changed_char = TA_NAME;*/ tag->refcount = 1; if ((NULL == fgets((gchar*)buf, BUFSIZ, fp)) || ('\0' == *buf)) return FALSE; { gchar **fields; guint field_len; for (start = end = buf, status = TRUE; (TRUE == status); start = end, ++ end) { while ((*end < TA_NAME) && (*end != '\0') && (*end != '\n')) ++ end; if (('\0' == *end) || ('\n' == *end)) status = FALSE; /*changed_char = *end;*/ *end = '\0'; if (NULL == tag->name && !isprint(*start)) return FALSE; fields = g_strsplit((gchar*)start, "|", -1); field_len = g_strv_length(fields); if (field_len >= 1) tag->name = g_strdup(fields[0]); else tag->name = NULL; if (field_len >= 2 && fields[1] != NULL) tag->var_type = g_strdup(fields[1]); if (field_len >= 3 && fields[2] != NULL) tag->arglist = g_strdup(fields[2]); tag->type = tm_tag_prototype_t; g_strfreev(fields); } } if (NULL == tag->name) return FALSE; tag->file = file; return TRUE; } static void read_ctags_file(const gchar *tags_file, TMParserType lang, GPtrArray *file_tags) { tagEntry entry; tagFile *f = tagsOpen(tags_file, NULL); const gchar *lang_kinds = tm_ctags_get_lang_kinds(lang); GArray *unknown_fields = g_array_sized_new(FALSE, FALSE, sizeof(guint), 10); while (tagsNext(f, &entry)) { TMTagType type; TMTag *tag; if (!entry.kind) continue; if (entry.kind[0] && entry.kind[1]) type = tm_parser_get_tag_type(tm_ctags_get_kind_from_name(entry.kind, lang), lang); /* 'K' field */ else type = tm_parser_get_tag_type(*entry.kind, lang); /* 'k' field */ if (type == tm_tag_undef_t) continue; tag = tm_tag_new(); tag->refcount = 1; tag->name = g_strdup(entry.name); tag->type = type; tag->lang = lang; tag->local = entry.fileScope; /* 'f' field */ tag->line = entry.address.lineNumber; /* 'n' field */ tag->file = NULL; if (tm_parser_is_anon_name(lang, tag->name)) tag->flags |= tm_tag_flag_anon_t; for (guint i = 0; i < entry.fields.count; i++) { const gchar *key = entry.fields.list[i].key; const gchar *value = entry.fields.list[i].value; if (strcmp(key, "scope") == 0) /* 'sZ' field */ { /* scope:class:A::B::C */ const gchar *val = strchr(value, ':'); if (val && *(++val)) { g_free(tag->scope); tag->scope = g_strdup(val); } } else if (strcmp(key, "signature") == 0) /* 'S' field */ { g_free(tag->arglist); tag->arglist = g_strdup(value); } else if (strcmp(key, "inherits") == 0) /* 'i' field */ { g_free(tag->inheritance); tag->inheritance = g_strdup(value); } else if (strcmp(key, "typeref") == 0) /* 't' field */ { /* typeref:typename:int */ const gchar *val = strchr(value, ':'); if (val && *(++val) && (g_str_has_prefix(value, "typename:") || g_str_has_prefix(value, "unknown:"))) { /* "unknown:" above is used by the php parser, all other parsers use "typename:" */ g_free(tag->var_type); tag->var_type = g_strdup(val); } } else if (strcmp(key, "extras") == 0) /* 'E' field */ { /* extras may contain multiple values such as extras:fileScope,anonymous */ if (strstr(value, "anonymous")) tag->flags |= tm_tag_flag_anon_t; } else if (strcmp(key, "implementation") == 0) /* 'm' field */ tag->impl = tm_source_file_get_tag_impl(value); else if (strcmp(key, "access") == 0) /* 'a' field */ tag->access = tm_source_file_get_tag_access(value); else if (strcmp(key, "language") == 0) /* 'l' field */ { TMParserType tag_lang = tm_ctags_get_named_lang(value); if (tag_lang >= 0) tag->lang = tag_lang; } else g_array_append_val(unknown_fields, i); } if (!tag->scope) { /* search for scope introduced by scope kind name only after going * through all extension fields and having tag->lang updated when * "language" field is present */ for (guint i = 0; !tag->scope && i < unknown_fields->len; i++) { const guint idx = g_array_index(unknown_fields, guint, i); const gchar *key = entry.fields.list[idx].key; const gchar *value = entry.fields.list[idx].value; for (gint j = 0; lang_kinds[j]; j++) { const gchar kind = lang_kinds[j]; const gchar *name = tm_ctags_get_kind_name(kind, tag->lang); if (strcmp(key, name) == 0) { /* 's' field - scope without the 'scope:' prefix */ tag->scope = g_strdup(value); break; } } } } unknown_fields->len = 0; g_ptr_array_add(file_tags, tag); } g_array_unref(unknown_fields); tagsClose(f); } static TMTag *new_tag_from_tags_file(TMSourceFile *file, FILE *fp, TMParserType mode, TMFileFormat format) { TMTag *tag = tm_tag_new(); gboolean result = FALSE; switch (format) { case TM_FILE_FORMAT_TAGMANAGER: result = init_tag_from_file(tag, file, fp, mode); break; case TM_FILE_FORMAT_PIPE: result = init_tag_from_file_alt(tag, file, fp); break; case TM_FILE_FORMAT_CTAGS: g_warn_if_reached(); /* this should never be reached; ctags files are handled separately */ break; } if (! result) { tm_tag_unref(tag); return NULL; } tag->lang = mode; return tag; } /* Writes tag information to the given FILE *. @param tag The tag information to write. @param file FILE pointer to which the tag information is written. @param attrs Attributes to be written (bitmask). @return TRUE on success, FALSE on failure. */ static gboolean write_tag(TMTag *tag, FILE *fp, TMTagAttrType attrs) { fprintf(fp, "%s", tag->name); if (attrs & tm_tag_attr_type_t) fprintf(fp, "%c%d", TA_TYPE, tag->type); if ((attrs & tm_tag_attr_arglist_t) && (NULL != tag->arglist)) fprintf(fp, "%c%s", TA_ARGLIST, tag->arglist); if (attrs & tm_tag_attr_line_t) fprintf(fp, "%c%ld", TA_LINE, tag->line); if (attrs & tm_tag_attr_local_t) fprintf(fp, "%c%d", TA_LOCAL, tag->local); if ((attrs & tm_tag_attr_scope_t) && (NULL != tag->scope)) fprintf(fp, "%c%s", TA_SCOPE, tag->scope); if ((attrs & tm_tag_attr_inheritance_t) && (NULL != tag->inheritance)) fprintf(fp, "%c%s", TA_INHERITS, tag->inheritance); if (attrs & tm_tag_attr_flags_t) fprintf(fp, "%c%d", TA_FLAGS, tag->flags); if ((attrs & tm_tag_attr_vartype_t) && (NULL != tag->var_type)) fprintf(fp, "%c%s", TA_VARTYPE, tag->var_type); if ((attrs & tm_tag_attr_access_t) && (TAG_ACCESS_UNKNOWN != tag->access)) fprintf(fp, "%c%c", TA_ACCESS, tag->access); if ((attrs & tm_tag_attr_impl_t) && (TAG_IMPL_UNKNOWN != tag->impl)) fprintf(fp, "%c%c", TA_IMPL, tag->impl); if (fprintf(fp, "\n")) return TRUE; else return FALSE; } GPtrArray *tm_source_file_read_tags_file(const gchar *tags_file, TMParserType mode) { guchar buf[BUFSIZ]; FILE *fp; GPtrArray *file_tags; TMTag *tag; TMFileFormat format = TM_FILE_FORMAT_TAGMANAGER; if (NULL == (fp = g_fopen(tags_file, "r"))) return NULL; if ((NULL == fgets((gchar*) buf, BUFSIZ, fp)) || ('\0' == *buf)) { fclose(fp); return NULL; /* early out on error */ } else { /* We read (and discard) the first line for the format specification. */ if (buf[0] == '#' && strstr((gchar*) buf, "format=pipe") != NULL) format = TM_FILE_FORMAT_PIPE; else if (buf[0] == '#' && strstr((gchar*) buf, "format=tagmanager") != NULL) format = TM_FILE_FORMAT_TAGMANAGER; else if (buf[0] == '#' && strstr((gchar*) buf, "format=ctags") != NULL) { format = TM_FILE_FORMAT_CTAGS; g_warning("# format=ctags directive is no longer supported; please remove it from %s", tags_file); } else if (strncmp((gchar*) buf, "!_TAG_", 6) == 0) format = TM_FILE_FORMAT_CTAGS; else { /* We didn't find a valid format specification, so we try to auto-detect the format * by counting the pipe characters on the first line and asumme pipe format when * we find more than one pipe on the line. */ guint i, pipe_cnt = 0, tab_cnt = 0; for (i = 0; i < BUFSIZ && buf[i] != '\0' && pipe_cnt < 2; i++) { if (buf[i] == '|') pipe_cnt++; else if (buf[i] == '\t') tab_cnt++; } if (pipe_cnt > 1) format = TM_FILE_FORMAT_PIPE; else if (tab_cnt > 1) format = TM_FILE_FORMAT_CTAGS; /* reset the file pointer, to start reading again from the beginning */ rewind(fp); } } file_tags = g_ptr_array_new(); if (format == TM_FILE_FORMAT_CTAGS) { fclose(fp); /* the readtags library opens the file by itself */ read_ctags_file(tags_file, mode, file_tags); } else { while (NULL != (tag = new_tag_from_tags_file(NULL, fp, mode, format))) g_ptr_array_add(file_tags, tag); fclose(fp); } return file_tags; } gboolean tm_source_file_write_tags_file(const gchar *tags_file, GPtrArray *tags_array) { guint i; FILE *fp; gboolean ret = TRUE; g_return_val_if_fail(tags_array && tags_file, FALSE); fp = g_fopen(tags_file, "w"); if (!fp) return FALSE; fprintf(fp, "# format=tagmanager\n"); for (i = 0; i < tags_array->len; i++) { TMTag *tag = TM_TAG(tags_array->pdata[i]); ret = write_tag(tag, fp, tm_tag_attr_type_t | tm_tag_attr_scope_t | tm_tag_attr_arglist_t | tm_tag_attr_vartype_t | tm_tag_attr_flags_t); if (!ret) break; } fclose(fp); return ret; } /* Initializes a TMSourceFile structure from a file name. */ static gboolean tm_source_file_init(TMSourceFile *source_file, const char *file_name, const char* name) { GStatBuf s; int status; #ifdef TM_DEBUG g_message("Source File init: %s", file_name); #endif if (file_name != NULL) { status = g_stat(file_name, &s); if (0 != status) { /* g_warning("Unable to stat %s", file_name);*/ return FALSE; } if (!S_ISREG(s.st_mode)) { g_warning("%s: Not a regular file", file_name); return FALSE; } source_file->file_name = tm_get_real_path(file_name); source_file->short_name = strrchr(source_file->file_name, G_DIR_SEPARATOR); if (source_file->short_name) ++ source_file->short_name; else source_file->short_name = source_file->file_name; } source_file->tags_array = g_ptr_array_new(); if (name == NULL) source_file->lang = TM_PARSER_NONE; else source_file->lang = tm_ctags_get_named_lang(name); source_file->trust_file_scope = TRUE; if (source_file->lang == TM_PARSER_C || source_file->lang == TM_PARSER_CPP) { const gchar **ext; const gchar *common_src_exts[] = {".c", ".C", ".cc", ".cp", ".cpp", ".cxx", ".c++", ".CPP", ".CXX", NULL}; source_file->trust_file_scope = FALSE; for (ext = common_src_exts; *ext; ext++) { if (g_str_has_suffix(source_file->short_name, *ext)) { source_file->trust_file_scope = TRUE; break; } } } return TRUE; } /** Initializes a TMSourceFile structure and returns a pointer to it. The * TMSourceFile has to be added to TMWorkspace to start its parsing. * @param file_name The file name. * @param name Name of the used programming language, NULL to disable parsing. * @return The created unparsed TMSourceFile object. * */ GEANY_API_SYMBOL TMSourceFile *tm_source_file_new(const char *file_name, const char *name) { TMSourceFilePriv *priv; SOURCE_FILE_NEW(priv); if (TRUE != tm_source_file_init(&priv->public, file_name, name)) { SOURCE_FILE_FREE(priv); return NULL; } priv->refcount = 1; return &priv->public; } static TMSourceFile *tm_source_file_dup(TMSourceFile *source_file) { TMSourceFilePriv *priv = (TMSourceFilePriv *) source_file; g_return_val_if_fail(NULL != source_file, NULL); g_atomic_int_inc(&priv->refcount); return source_file; } /* Destroys the contents of the source file. Note that the tags are owned by the source file and are also destroyed when the source file is destroyed. If pointers to these tags are used elsewhere, then those tag arrays should be rebuilt. */ static void tm_source_file_destroy(TMSourceFile *source_file) { #ifdef TM_DEBUG g_message("Destroying source file: %s", source_file->file_name); #endif g_free(source_file->file_name); tm_tags_array_free(source_file->tags_array, TRUE); source_file->tags_array = NULL; } /** Decrements the reference count of @a source_file * * If the reference count drops to 0, then @a source_file is freed, including all contents. * Make sure the @a source_file is already removed from any TMWorkSpace before the * this happens. * @param source_file The source file to free. * @see tm_workspace_remove_source_file() */ GEANY_API_SYMBOL void tm_source_file_free(TMSourceFile *source_file) { TMSourceFilePriv *priv = (TMSourceFilePriv *) source_file; if (NULL != priv && g_atomic_int_dec_and_test(&priv->refcount)) { tm_source_file_destroy(source_file); SOURCE_FILE_FREE(priv); } } /** Gets the GBoxed-derived GType for TMSourceFile * * @return TMSourceFile type . */ GEANY_API_SYMBOL GType tm_source_file_get_type(void); G_DEFINE_BOXED_TYPE(TMSourceFile, tm_source_file, tm_source_file_dup, tm_source_file_free); /* Parses the text-buffer or source file and regenarates the tags. @param source_file The source file to parse @param text_buf The text buffer to parse @param buf_size The size of text_buf. @param use_buffer Set FALSE to ignore the buffer and parse the file directly or TRUE to parse the buffer and ignore the file content. @return TRUE on success, FALSE on failure */ gboolean tm_source_file_parse(TMSourceFile *source_file, guchar* text_buf, gsize buf_size, gboolean use_buffer) { const char *file_name; gboolean retry = TRUE; if ((NULL == source_file) || (NULL == source_file->file_name)) { g_warning("Attempt to parse NULL file"); return FALSE; } if (source_file->lang == TM_PARSER_NONE) { tm_tags_array_free(source_file->tags_array, FALSE); return FALSE; } file_name = source_file->file_name; if (use_buffer && (NULL == text_buf || 0 == buf_size)) { /* Empty buffer, "parse" by setting empty tag array */ tm_tags_array_free(source_file->tags_array, FALSE); return TRUE; } tm_tags_array_free(source_file->tags_array, FALSE); tm_ctags_parse(use_buffer ? text_buf : NULL, buf_size, file_name, source_file->lang, source_file); return !retry; } /* Gets the name associated with the language index. @param lang The language index. @return The language name, or NULL. */ const gchar *tm_source_file_get_lang_name(TMParserType lang) { return tm_ctags_get_lang_name(lang); } /* Gets the language index for \a name. @param name The language name. @return The language index, or TM_PARSER_NONE. */ TMParserType tm_source_file_get_named_lang(const gchar *name) { return tm_ctags_get_named_lang(name); } geany-2.0/src/tagmanager/tm_tag.c0000644000175000017500000004776314514252267013744 00000000000000/* * * Copyright (c) 2001-2002, Biswapesh Chattopadhyay * Copyright 2005 The Geany contributors * * This source code is released for free distribution under the terms of the * GNU General Public License. * */ #include #include #include #include "tm_tag.h" #include "tm_ctags.h" #define TAG_NEW(T) ((T) = g_slice_new0(TMTag)) #define TAG_FREE(T) g_slice_free(TMTag, (T)) #ifdef DEBUG_TAG_REFS static GHashTable *alive_tags = NULL; static void foreach_tags_log(gpointer key, gpointer value, gpointer data) { gsize *ref_count = data; const TMTag *tag = value; *ref_count += (gsize) tag->refcount; g_debug("Leaked TMTag (%d refs): %s", tag->refcount, tag->name); } static void log_refs_at_exit(void) { gsize ref_count = 0; g_hash_table_foreach(alive_tags, foreach_tags_log, &ref_count); g_debug("TMTag references left at exit: %lu", ref_count); } static TMTag *log_tag_new(void) { TMTag *tag; if (! alive_tags) { alive_tags = g_hash_table_new(g_direct_hash, g_direct_equal); atexit(log_refs_at_exit); } TAG_NEW(tag); g_hash_table_insert(alive_tags, tag, tag); return tag; } static void log_tag_free(TMTag *tag) { g_return_if_fail(alive_tags != NULL); if (! g_hash_table_remove(alive_tags, tag)) { g_critical("Freeing invalid TMTag pointer %p", (void *) tag); } else { TAG_FREE(tag); } } #undef TAG_NEW #undef TAG_FREE #define TAG_NEW(T) ((T) = log_tag_new()) #define TAG_FREE(T) log_tag_free(T) #endif /* DEBUG_TAG_REFS */ typedef struct { guint *sort_attrs; gboolean partial; const GPtrArray *tags_array; gboolean first; } TMSortOptions; /** Gets the GType for a TMTag. * * @return TMTag type * @since 1.32 (API 233) */ GEANY_API_SYMBOL GType tm_tag_get_type(void) { static GType gtype = 0; if (G_UNLIKELY (gtype == 0)) { gtype = g_boxed_type_register_static("TMTag", (GBoxedCopyFunc)tm_tag_ref, (GBoxedFreeFunc)tm_tag_unref); } return gtype; } /* Creates a new tag structure and returns a pointer to it. @return the new TMTag structure. This should be free()-ed using tm_tag_free() */ TMTag *tm_tag_new(void) { TMTag *tag; TAG_NEW(tag); tag->refcount = 1; return tag; } /* Destroys a TMTag structure, i.e. frees all elements except the tag itself. @param tag The TMTag structure to destroy @see tm_tag_free() */ static void tm_tag_destroy(TMTag *tag) { g_free(tag->name); g_free(tag->arglist); g_free(tag->scope); g_free(tag->inheritance); g_free(tag->var_type); } /* Drops a reference from a TMTag. If the reference count reaches 0, this function destroys all data in the tag and frees the tag structure as well. @param tag Pointer to a TMTag structure */ void tm_tag_unref(TMTag *tag) { /* be NULL-proof because tm_tag_free() was NULL-proof and we indent to be a * drop-in replacment of it */ if (NULL != tag && g_atomic_int_dec_and_test(&tag->refcount)) { tm_tag_destroy(tag); TAG_FREE(tag); } } /* Adds a reference to a TMTag. @param tag Pointer to a TMTag structure @return the passed-in TMTag */ TMTag *tm_tag_ref(TMTag *tag) { g_atomic_int_inc(&tag->refcount); return tag; } /* Inbuilt tag comparison function. */ static gint tm_tag_compare(gconstpointer ptr1, gconstpointer ptr2, gpointer user_data) { unsigned int *sort_attr; int returnval = 0; TMTag *t1 = *((TMTag **) ptr1); TMTag *t2 = *((TMTag **) ptr2); TMSortOptions *sort_options = user_data; if ((NULL == t1) || (NULL == t2)) { g_warning("Found NULL tag"); return t2 - t1; } if (NULL == sort_options->sort_attrs) { if (sort_options->partial) return strncmp(FALLBACK(t1->name, ""), FALLBACK(t2->name, ""), strlen(FALLBACK(t1->name, ""))); else return strcmp(FALLBACK(t1->name, ""), FALLBACK(t2->name, "")); } for (sort_attr = sort_options->sort_attrs; returnval == 0 && *sort_attr != tm_tag_attr_none_t; ++ sort_attr) { switch (*sort_attr) { case tm_tag_attr_name_t: if (sort_options->partial) returnval = strncmp(FALLBACK(t1->name, ""), FALLBACK(t2->name, ""), strlen(FALLBACK(t1->name, ""))); else returnval = strcmp(FALLBACK(t1->name, ""), FALLBACK(t2->name, "")); break; case tm_tag_attr_file_t: returnval = t1->file - t2->file; break; case tm_tag_attr_line_t: returnval = t1->line - t2->line; break; case tm_tag_attr_type_t: returnval = t1->type - t2->type; break; case tm_tag_attr_scope_t: returnval = strcmp(FALLBACK(t1->scope, ""), FALLBACK(t2->scope, "")); break; case tm_tag_attr_arglist_t: returnval = strcmp(FALLBACK(t1->arglist, ""), FALLBACK(t2->arglist, "")); if (returnval != 0) { int line_diff = (t1->line - t2->line); returnval = line_diff ? line_diff : returnval; } break; case tm_tag_attr_vartype_t: returnval = strcmp(FALLBACK(t1->var_type, ""), FALLBACK(t2->var_type, "")); break; } } return returnval; } gboolean tm_tags_equal(const TMTag *a, const TMTag *b) { if (a == b) return TRUE; return (a->line == b->line && a->file == b->file /* ptr comparison */ && strcmp(FALLBACK(a->name, ""), FALLBACK(b->name, "")) == 0 && a->type == b->type && a->local == b->local && a->flags == b->flags && a->access == b->access && a->impl == b->impl && a->lang == b->lang && strcmp(FALLBACK(a->scope, ""), FALLBACK(b->scope, "")) == 0 && strcmp(FALLBACK(a->arglist, ""), FALLBACK(b->arglist, "")) == 0 && strcmp(FALLBACK(a->inheritance, ""), FALLBACK(b->inheritance, "")) == 0 && strcmp(FALLBACK(a->var_type, ""), FALLBACK(b->var_type, "")) == 0); } /* Removes NULL tag entries from an array of tags. Called after tm_tags_dedup() since this function substitutes duplicate entries with NULL @param tags_array Array of tags to dedup */ void tm_tags_prune(GPtrArray *tags_array) { guint i, count; g_return_if_fail(tags_array); for (i=0, count = 0; i < tags_array->len; ++i) { if (NULL != tags_array->pdata[i]) tags_array->pdata[count++] = tags_array->pdata[i]; } tags_array->len = count; } /* Deduplicates an array on tags using the inbuilt comparison function based on the attributes specified. Called by tm_tags_sort() when dedup is TRUE. @param tags_array Array of tags to dedup. @param sort_attributes Attributes the array is sorted on. They will be deduped on the same criteria. */ void tm_tags_dedup(GPtrArray *tags_array, TMTagAttrType *sort_attributes, gboolean unref_duplicates) { TMSortOptions sort_options; guint i; g_return_if_fail(tags_array); if (tags_array->len < 2) return; sort_options.sort_attrs = sort_attributes; sort_options.partial = FALSE; for (i = 1; i < tags_array->len; ++i) { if (0 == tm_tag_compare(&(tags_array->pdata[i - 1]), &(tags_array->pdata[i]), &sort_options)) { if (unref_duplicates) tm_tag_unref(tags_array->pdata[i-1]); tags_array->pdata[i-1] = NULL; } } tm_tags_prune(tags_array); } /* Sort an array of tags on the specified attribuites using the inbuilt comparison function. @param tags_array The array of tags to be sorted @param sort_attributes Attributes to be sorted on (int array terminated by 0) @param dedup Whether to deduplicate the sorted array */ void tm_tags_sort(GPtrArray *tags_array, TMTagAttrType *sort_attributes, gboolean dedup, gboolean unref_duplicates) { TMSortOptions sort_options; g_return_if_fail(tags_array); sort_options.sort_attrs = sort_attributes; sort_options.partial = FALSE; g_ptr_array_sort_with_data(tags_array, tm_tag_compare, &sort_options); if (dedup) tm_tags_dedup(tags_array, sort_attributes, unref_duplicates); } void tm_tags_remove_file_tags(TMSourceFile *source_file, GPtrArray *tags_array) { guint i; /* Now we choose between an algorithm with complexity O(tags_array->len) and * O(source_file->tags_array->len * log(tags_array->len)). The latter algorithm * is better when tags_array contains many times more tags than * source_file->tags_array so instead of trying to find the removed tags * linearly, binary search is used. The constant 20 is more or less random * but seems to work well. It's exact value isn't so critical because it's * the extremes where the difference is the biggest: when * source_file->tags_array->len == tags_array->len (single file open) and * source_file->tags_array->len << tags_array->len (the number of tags * from the file is a small fraction of all tags). */ if (source_file->tags_array->len != 0 && tags_array->len / source_file->tags_array->len < 20) { for (i = 0; i < tags_array->len; i++) { TMTag *tag = tags_array->pdata[i]; if (tag->file == source_file) tags_array->pdata[i] = NULL; } } else { GPtrArray *to_delete = g_ptr_array_sized_new(source_file->tags_array->len); for (i = 0; i < source_file->tags_array->len; i++) { guint j; guint tag_count; TMTag **found; TMTag *tag = source_file->tags_array->pdata[i]; found = tm_tags_find(tags_array, tag->name, FALSE, &tag_count); for (j = 0; j < tag_count; j++) { if (*found != NULL && (*found)->file == source_file) { /* we cannot set the pointer to NULL now because the search wouldn't work */ g_ptr_array_add(to_delete, found); /* no break - if there are multiple tags of the same name, we would * always find the first instance and wouldn't remove others; duplicates * in the to_delete list aren't a problem */ } found++; } } for (i = 0; i < to_delete->len; i++) { TMTag **tag = to_delete->pdata[i]; *tag = NULL; } g_ptr_array_free(to_delete, TRUE); } tm_tags_prune(tags_array); } /* Optimized merge sort for merging sorted values from one array to another * where one of the arrays is much smaller than the other. * The merge complexity depends mostly on the size of the small array * and is almost independent of the size of the big array. * In addition, get rid of the duplicates (if both big_array and small_array are duplicate-free). */ static GPtrArray *merge(GPtrArray *big_array, GPtrArray *small_array, TMSortOptions *sort_options, gboolean unref_duplicates) { guint i1 = 0; /* index to big_array */ guint i2 = 0; /* index to small_array */ guint initial_step; guint step; GPtrArray *res_array = g_ptr_array_sized_new(big_array->len + small_array->len); #ifdef TM_DEBUG guint cmpnum = 0; #endif /* swap the arrays if len(small) > len(big) */ if (small_array->len > big_array->len) { GPtrArray *tmp = small_array; small_array = big_array; big_array = tmp; } /* on average, we are merging a value from small_array every * len(big_array) / len(small_array) values - good approximation for fast jump * step size */ initial_step = (small_array->len > 0) ? big_array->len / small_array->len : 1; initial_step = initial_step > 4 ? initial_step : 1; step = initial_step; while (i1 < big_array->len && i2 < small_array->len) { gpointer val1; gpointer val2 = small_array->pdata[i2]; if (step > 4) /* fast path start */ { guint j1 = (i1 + step < big_array->len) ? i1 + step : big_array->len - 1; val1 = big_array->pdata[j1]; #ifdef TM_DEBUG cmpnum++; #endif /* if the value in big_array after making the big step is still smaller * than the value in small_array, we can copy all the values inbetween * into the result without making expensive string comparisons */ if (tm_tag_compare(&val1, &val2, sort_options) < 0) { while (i1 <= j1) { val1 = big_array->pdata[i1]; g_ptr_array_add(res_array, val1); i1++; } } else { /* lower the step and try again */ step /= 2; } } /* fast path end */ else { gint cmpval; #ifdef TM_DEBUG cmpnum++; #endif val1 = big_array->pdata[i1]; cmpval = tm_tag_compare(&val1, &val2, sort_options); if (cmpval < 0) { g_ptr_array_add(res_array, val1); i1++; } else { g_ptr_array_add(res_array, val2); i2++; /* value from small_array gets merged - reset the step size */ step = initial_step; if (cmpval == 0) { i1++; /* remove the duplicate, keep just the newly merged value */ if (unref_duplicates) tm_tag_unref(val1); } } } } /* end of one of the arrays reached - copy the rest from the other array */ while (i1 < big_array->len) g_ptr_array_add(res_array, big_array->pdata[i1++]); while (i2 < small_array->len) g_ptr_array_add(res_array, small_array->pdata[i2++]); #ifdef TM_DEBUG printf("cmpnums: %u\n", cmpnum); printf("total tags: %u\n", big_array->len); printf("merged tags: %u\n\n", small_array->len); #endif return res_array; } GPtrArray *tm_tags_merge(GPtrArray *big_array, GPtrArray *small_array, TMTagAttrType *sort_attributes, gboolean unref_duplicates) { GPtrArray *res_array; TMSortOptions sort_options; sort_options.sort_attrs = sort_attributes; sort_options.partial = FALSE; res_array = merge(big_array, small_array, &sort_options, unref_duplicates); return res_array; } /* This function will extract the tags of the specified types from an array of tags. The returned value is a GPtrArray which should be free-d with a call to g_ptr_array_free(array, TRUE). However, do not free the tags themselves since they are not duplicated. @param tags_array The original array of tags @param tag_types - The tag types to extract. Can be a bitmask. For example, passing (tm_tag_typedef_t | tm_tag_struct_t) will extract all typedefs and structures from the original array. @return an array of tags (NULL on failure) */ GPtrArray *tm_tags_extract(GPtrArray *tags_array, TMTagType tag_types) { GPtrArray *new_tags; guint i; g_return_val_if_fail(tags_array, NULL); new_tags = g_ptr_array_new(); for (i=0; i < tags_array->len; ++i) { if (NULL != tags_array->pdata[i]) { if (tag_types & (((TMTag *) tags_array->pdata[i])->type)) g_ptr_array_add(new_tags, tags_array->pdata[i]); } } return new_tags; } /* Completely frees an array of tags. @param tags_array Array of tags to be freed. @param free_array Whether the GptrArray is to be freed as well. */ void tm_tags_array_free(GPtrArray *tags_array, gboolean free_all) { if (tags_array) { guint i; for (i = 0; i < tags_array->len; ++i) tm_tag_unref(tags_array->pdata[i]); if (free_all) g_ptr_array_free(tags_array, TRUE); else g_ptr_array_set_size(tags_array, 0); } } /* copy/pasted bsearch() from libc extended with user_data for comparison function * and using glib types */ static gpointer binary_search(gpointer key, gpointer base, size_t nmemb, GCompareDataFunc compar, gpointer user_data) { gsize l, u, idx; gpointer p; gint comparison; l = 0; u = nmemb; while (l < u) { idx = (l + u) / 2; p = (gpointer) (((const gchar *) base) + (idx * sizeof(gpointer))); comparison = (*compar) (key, p, user_data); if (comparison < 0) u = idx; else if (comparison > 0) l = idx + 1; else return (gpointer) p; } return NULL; } static gint tag_search_cmp(gconstpointer ptr1, gconstpointer ptr2, gpointer user_data) { gint res = tm_tag_compare(ptr1, ptr2, user_data); if (res == 0) { TMSortOptions *sort_options = user_data; const GPtrArray *tags_array = sort_options->tags_array; TMTag **tag = (TMTag **) ptr2; /* if previous/next (depending on sort options) tag equal, we haven't * found the first/last tag in a sequence of equal tags yet */ if (sort_options->first && ptr2 != &tags_array->pdata[0]) { if (tm_tag_compare(ptr1, tag - 1, user_data) == 0) return -1; } else if (!sort_options->first && ptr2 != &tags_array->pdata[tags_array->len-1]) { if (tm_tag_compare(ptr1, tag + 1, user_data) == 0) return 1; } } return res; } /* Returns a pointer to the position of the first matching tag in a (sorted) tags array. The passed array of tags must be already sorted by name (searched with binary search). @param tags_array Tag array (sorted on name) @param name Name of the tag to locate. @param partial If TRUE, matches the first part of the name instead of doing exact match. @param tagCount Return location of the matched tags. */ TMTag **tm_tags_find(const GPtrArray *tags_array, const char *name, gboolean partial, guint *tagCount) { TMTag *tag, **first; TMSortOptions sort_options; *tagCount = 0; if (!tags_array || !tags_array->len) return NULL; tag = g_new0(TMTag, 1); tag->name = (char *) name; sort_options.sort_attrs = NULL; sort_options.partial = partial; sort_options.tags_array = tags_array; sort_options.first = TRUE; first = (TMTag **)binary_search(&tag, tags_array->pdata, tags_array->len, tag_search_cmp, &sort_options); if (first) { TMTag **last; unsigned first_pos; sort_options.first = FALSE; first_pos = first - (TMTag **)tags_array->pdata; /* search between the first element and end */ last = (TMTag **)binary_search(&tag, first, tags_array->len - first_pos, tag_search_cmp, &sort_options); *tagCount = last - first + 1; } g_free(tag); return (TMTag **) first; } /* Returns TMTag which "own" given line @param line Current line in edited file. @param file_tags A GPtrArray of edited file TMTag pointers. @param tag_types the tag types to include in the match @return TMTag pointers to owner tag. */ const TMTag * tm_get_current_tag (GPtrArray * file_tags, const gulong line, const TMTagType tag_types) { TMTag *matching_tag = NULL; if (file_tags && file_tags->len) { guint i; gulong matching_line = 0; for (i = 0; (i < file_tags->len); ++i) { TMTag *tag = TM_TAG (file_tags->pdata[i]); if (tag && tag->type & tag_types && tag->line <= line && tag->line > matching_line) { matching_tag = tag; matching_line = tag->line; } } } return matching_tag; } gboolean tm_tag_is_anon(const TMTag *tag) { return tag->flags & tm_tag_flag_anon_t; } #ifdef TM_DEBUG /* various debugging functions */ /* Returns the type of tag as a string @param tag The tag whose type is required */ const char *tm_tag_type_name(const TMTag *tag) { g_return_val_if_fail(tag, NULL); return tm_ctags_get_kind_name(tm_parser_get_tag_kind(tag->type, tag->lang), tag->lang); } /* Returns the TMTagType given the name of the type. Reverse of tm_tag_type_name. @param tag_name Name of the tag type */ TMTagType tm_tag_name_type(const char* tag_name, TMParserType lang) { g_return_val_if_fail(tag_name, tm_tag_undef_t); return tm_parser_get_tag_type(tm_ctags_get_kind_from_name(tag_name, lang), lang); } static const char *tm_tag_impl_name(TMTag *tag) { g_return_val_if_fail(tag, NULL); if (TAG_IMPL_VIRTUAL == tag->impl) return "virtual"; else return NULL; } static const char *tm_tag_access_name(TMTag *tag) { g_return_val_if_fail(tag, NULL); if (TAG_ACCESS_PUBLIC == tag->access) return "public"; else if (TAG_ACCESS_PROTECTED == tag->access) return "protected"; else if (TAG_ACCESS_PRIVATE == tag->access) return "private"; else return NULL; } /* Prints information about a tag to the given file pointer. @param tag The tag whose info is required. @param fp The file pointer of the file to print the info to. */ void tm_tag_print(TMTag *tag, FILE *fp) { const char *laccess, *impl, *type; if (!tag || !fp) return; laccess = tm_tag_access_name(tag); impl = tm_tag_impl_name(tag); type = tm_tag_type_name(tag); if (laccess) fprintf(fp, "%s ", laccess); if (impl) fprintf(fp, "%s ", impl); if (type) fprintf(fp, "%s ", type); if (tag->var_type) fprintf(fp, "%s ", tag->var_type); if (tag->scope) fprintf(fp, "%s::", tag->scope); fprintf(fp, "%s", tag->name); if (tag->arglist) fprintf(fp, "%s", tag->arglist); if (tag->inheritance) fprintf(fp, " : from %s", tag->inheritance); if ((tag->file) && (tag->line > 0)) fprintf(fp, "[%s:%ld]", tag->file->file_name , tag->line); fprintf(fp, "\n"); } /* Prints info about all tags in the array to the given file pointer. */ void tm_tags_array_print(GPtrArray *tags, FILE *fp) { guint i; TMTag *tag; if (!(tags && (tags->len > 0) && fp)) return; for (i = 0; i < tags->len; ++i) { tag = TM_TAG(tags->pdata[i]); tm_tag_print(tag, fp); } } /* Returns the depth of tag scope (useful for finding tag hierarchy */ gint tm_tag_scope_depth(const TMTag *t) { const gchar *context_sep = tm_parser_scope_separator(t->lang); gint depth; char *s; if(!(t && t->scope)) return 0; for (s = t->scope, depth = 0; s; s = strstr(s, context_sep)) { ++ depth; ++ s; } return depth; } #endif /* TM_DEBUG */ geany-2.0/src/tagmanager/tm_parser.c0000644000175000017500000015346414514252267014461 00000000000000/* * tm_parser.c - this file is part of Geany, a fast and lightweight IDE * * Copyright 2016 The Geany contributors * * This program 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; either version 2 of the License, or * (at your option) any later version. * * This program 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "tm_parser.h" #include "tm_ctags.h" #include #include "config.h" #ifdef GETTEXT_PACKAGE # include #else # define _(String) String # define N_(String) String #endif typedef struct { const gchar kind; TMTagType type; } TMParserMapEntry; /* Allows remapping a subparser tag type to another type if there's a clash with * the master parser tag type. Only subparser tag types explicitly listed within * TMSubparserMapEntry maps are added to tag manager - tags with types not listed * are discarded to prevent uncontrolled merging of tags from master parser and * subparsers. */ typedef struct { TMTagType orig_type; TMTagType new_type; } TMSubparserMapEntry; typedef struct { const gchar *name; guint icon; TMTagType types; } TMParserMapGroup; static GHashTable *subparser_map = NULL; #define COMMON_C \ {'d', tm_tag_macro_t}, /* macro */ \ {'e', tm_tag_enumerator_t}, /* enumerator */ \ {'f', tm_tag_function_t}, /* function */ \ {'g', tm_tag_enum_t}, /* enum */ \ {'m', tm_tag_member_t}, /* member */ \ {'p', tm_tag_prototype_t}, /* prototype */ \ {'s', tm_tag_struct_t}, /* struct */ \ {'t', tm_tag_typedef_t}, /* typedef */ \ {'u', tm_tag_union_t}, /* union */ \ {'v', tm_tag_variable_t}, /* variable */ \ {'x', tm_tag_externvar_t}, /* externvar */ \ {'h', tm_tag_include_t}, /* header */ \ {'l', tm_tag_local_var_t}, /* local */ \ {'z', tm_tag_local_var_t}, /* parameter */ \ {'L', tm_tag_undef_t}, /* label */ \ {'D', tm_tag_undef_t}, /* macroparam */ static TMParserMapEntry map_C[] = { COMMON_C }; /* Used also by other languages than C - keep all the tm_tag_* here even though * they aren't used by C as they might be used by some other language */ static TMParserMapGroup group_C[] = { {N_("Namespaces"), TM_ICON_NAMESPACE, tm_tag_namespace_t | tm_tag_package_t | tm_tag_include_t}, {N_("Classes"), TM_ICON_CLASS, tm_tag_class_t}, {N_("Interfaces"), TM_ICON_STRUCT, tm_tag_interface_t}, {N_("Functions"), TM_ICON_METHOD, tm_tag_prototype_t | tm_tag_method_t | tm_tag_function_t}, {N_("Members"), TM_ICON_MEMBER, tm_tag_member_t | tm_tag_field_t}, {N_("Structs"), TM_ICON_STRUCT, tm_tag_union_t | tm_tag_struct_t}, {N_("Typedefs / Enums"), TM_ICON_STRUCT, tm_tag_typedef_t | tm_tag_enum_t}, {N_("Macros"), TM_ICON_MACRO, tm_tag_macro_t | tm_tag_macro_with_arg_t}, {N_("Variables"), TM_ICON_VAR, tm_tag_variable_t | tm_tag_enumerator_t | tm_tag_local_var_t}, {N_("Extern Variables"), TM_ICON_VAR, tm_tag_externvar_t}, {N_("Other"), TM_ICON_OTHER, tm_tag_other_t}, }; static TMParserMapEntry map_CPP[] = { COMMON_C {'c', tm_tag_class_t}, // class {'n', tm_tag_namespace_t}, // namespace {'A', tm_tag_undef_t}, // alias {'N', tm_tag_undef_t}, // name {'U', tm_tag_undef_t}, // using {'Z', tm_tag_undef_t}, // tparam }; #define group_CPP group_C static TMParserMapEntry map_JAVA[] = { {'c', tm_tag_class_t}, // class {'f', tm_tag_field_t}, // field {'i', tm_tag_interface_t}, // interface {'m', tm_tag_method_t}, // method {'p', tm_tag_package_t}, // package {'e', tm_tag_enumerator_t}, // enumConstant {'g', tm_tag_enum_t}, // enum }; static TMParserMapGroup group_JAVA[] = { {N_("Package"), TM_ICON_NAMESPACE, tm_tag_package_t}, {N_("Interfaces"), TM_ICON_STRUCT, tm_tag_interface_t}, {N_("Classes"), TM_ICON_CLASS, tm_tag_class_t}, {N_("Methods"), TM_ICON_METHOD, tm_tag_method_t}, {N_("Members"), TM_ICON_MEMBER, tm_tag_field_t}, {N_("Enums"), TM_ICON_STRUCT, tm_tag_enum_t}, {N_("Other"), TM_ICON_VAR, tm_tag_enumerator_t}, }; // no scope information static TMParserMapEntry map_MAKEFILE[] = { {'m', tm_tag_macro_t}, // macro {'t', tm_tag_function_t}, // target {'I', tm_tag_undef_t}, // makefile }; static TMParserMapGroup group_MAKEFILE[] = { {N_("Targets"), TM_ICON_METHOD, tm_tag_function_t}, {N_("Macros"), TM_ICON_MACRO, tm_tag_macro_t}, }; static TMParserMapEntry map_PASCAL[] = { {'f', tm_tag_function_t}, // function {'p', tm_tag_function_t}, // procedure }; static TMParserMapGroup group_PASCAL[] = { {N_("Functions"), TM_ICON_METHOD, tm_tag_function_t}, }; // no scope information static TMParserMapEntry map_PERL[] = { {'c', tm_tag_enum_t}, // constant {'f', tm_tag_other_t}, // format {'l', tm_tag_macro_t}, // label {'p', tm_tag_package_t}, // package {'s', tm_tag_function_t}, // subroutine {'d', tm_tag_prototype_t}, // subroutineDeclaration {'M', tm_tag_undef_t}, // module }; static TMParserMapGroup group_PERL[] = { {N_("Package"), TM_ICON_NAMESPACE, tm_tag_package_t}, {N_("Functions"), TM_ICON_METHOD, tm_tag_function_t | tm_tag_prototype_t}, {N_("Labels"), TM_ICON_NONE, tm_tag_macro_t}, {N_("Constants"), TM_ICON_NONE, tm_tag_enum_t}, {N_("Other"), TM_ICON_OTHER, tm_tag_other_t}, }; static TMParserMapEntry map_PHP[] = { {'c', tm_tag_class_t}, // class {'d', tm_tag_macro_t}, // define {'f', tm_tag_function_t}, // function {'i', tm_tag_interface_t}, // interface {'l', tm_tag_local_var_t}, // local {'n', tm_tag_namespace_t}, // namespace {'t', tm_tag_struct_t}, // trait {'v', tm_tag_variable_t}, // variable {'a', tm_tag_undef_t}, // alias }; static TMParserMapGroup group_PHP[] = { {N_("Namespaces"), TM_ICON_NAMESPACE, tm_tag_namespace_t}, {N_("Interfaces"), TM_ICON_STRUCT, tm_tag_interface_t}, {N_("Classes"), TM_ICON_CLASS, tm_tag_class_t}, {N_("Functions"), TM_ICON_METHOD, tm_tag_function_t}, {N_("Constants"), TM_ICON_MACRO, tm_tag_macro_t}, {N_("Variables"), TM_ICON_VAR, tm_tag_variable_t | tm_tag_local_var_t}, {N_("Traits"), TM_ICON_STRUCT, tm_tag_struct_t}, }; static TMParserMapEntry map_PYTHON[] = { {'c', tm_tag_class_t}, // class {'f', tm_tag_function_t}, // function {'m', tm_tag_method_t}, // member {'v', tm_tag_variable_t}, // variable {'I', tm_tag_externvar_t}, // namespace {'i', tm_tag_externvar_t}, // module /* defined as externvar to get those excluded as forward type in symbols.c:goto_tag() * so we can jump to the real implementation (if known) instead of to the import statement */ {'x', tm_tag_externvar_t}, // unknown {'z', tm_tag_local_var_t}, // parameter {'l', tm_tag_local_var_t}, // local }; static TMParserMapGroup group_PYTHON[] = { {N_("Classes"), TM_ICON_CLASS, tm_tag_class_t}, {N_("Methods"), TM_ICON_MACRO, tm_tag_method_t}, {N_("Functions"), TM_ICON_METHOD, tm_tag_function_t}, {N_("Variables"), TM_ICON_VAR, tm_tag_variable_t | tm_tag_local_var_t}, {N_("Imports"), TM_ICON_NAMESPACE, tm_tag_externvar_t}, }; static TMParserMapEntry map_LATEX[] = { {'p', tm_tag_enum_t}, // part {'c', tm_tag_namespace_t}, // chapter {'s', tm_tag_member_t}, // section {'u', tm_tag_macro_t}, // subsection {'b', tm_tag_variable_t}, // subsubsection {'P', tm_tag_undef_t}, // paragraph {'G', tm_tag_undef_t}, // subparagraph {'l', tm_tag_struct_t}, // label {'i', tm_tag_undef_t}, // xinput {'B', tm_tag_field_t}, // bibitem {'C', tm_tag_function_t}, // command {'o', tm_tag_function_t}, // operator {'e', tm_tag_class_t}, // environment {'t', tm_tag_class_t}, // theorem {'N', tm_tag_undef_t}, // counter }; static TMParserMapGroup group_LATEX[] = { {N_("Command"), TM_ICON_NONE, tm_tag_function_t}, {N_("Environment"), TM_ICON_NONE, tm_tag_class_t}, {N_("Part"), TM_ICON_NONE, tm_tag_enum_t}, {N_("Chapter"), TM_ICON_NONE, tm_tag_namespace_t}, {N_("Section"), TM_ICON_NONE, tm_tag_member_t}, {N_("Subsection"), TM_ICON_NONE, tm_tag_macro_t}, {N_("Subsubsection"), TM_ICON_NONE, tm_tag_variable_t}, {N_("Bibitem"), TM_ICON_NONE, tm_tag_field_t}, {N_("Label"), TM_ICON_NONE, tm_tag_struct_t}, }; // no scope information static TMParserMapEntry map_BIBTEX[] = { {'a', tm_tag_function_t}, // article {'b', tm_tag_class_t}, // book {'B', tm_tag_class_t}, // booklet {'c', tm_tag_member_t}, // conference {'i', tm_tag_macro_t}, // inbook {'I', tm_tag_macro_t}, // incollection {'j', tm_tag_member_t}, // inproceedings {'m', tm_tag_other_t}, // manual {'M', tm_tag_variable_t}, // mastersthesis {'n', tm_tag_other_t}, // misc {'p', tm_tag_variable_t}, // phdthesis {'P', tm_tag_class_t}, // proceedings {'s', tm_tag_namespace_t}, // string {'t', tm_tag_other_t}, // techreport {'u', tm_tag_externvar_t}, // unpublished }; static TMParserMapGroup group_BIBTEX[] = { {N_("Articles"), TM_ICON_NONE, tm_tag_function_t}, {N_("Book Chapters"), TM_ICON_NONE, tm_tag_macro_t}, {N_("Books & Conference Proceedings"), TM_ICON_NONE, tm_tag_class_t}, {N_("Conference Papers"), TM_ICON_NONE, tm_tag_member_t}, {N_("Theses"), TM_ICON_NONE, tm_tag_variable_t}, {N_("Strings"), TM_ICON_NONE, tm_tag_namespace_t}, {N_("Unpublished"), TM_ICON_NONE, tm_tag_externvar_t}, {N_("Other"), TM_ICON_NONE, tm_tag_other_t}, }; static TMParserMapEntry map_ASM[] = { {'d', tm_tag_macro_t}, // define {'l', tm_tag_namespace_t}, // label {'m', tm_tag_function_t}, // macro {'t', tm_tag_struct_t}, // type {'s', tm_tag_undef_t}, // section }; static TMParserMapGroup group_ASM[] = { {N_("Labels"), TM_ICON_NAMESPACE, tm_tag_namespace_t}, {N_("Macros"), TM_ICON_METHOD, tm_tag_function_t}, {N_("Defines"), TM_ICON_MACRO, tm_tag_macro_t}, {N_("Types"), TM_ICON_STRUCT, tm_tag_struct_t}, }; static TMParserMapEntry map_CONF[] = { {'s', tm_tag_namespace_t}, // section {'k', tm_tag_macro_t}, // key }; static TMParserMapGroup group_CONF[] = { {N_("Sections"), TM_ICON_OTHER, tm_tag_namespace_t}, {N_("Keys"), TM_ICON_VAR, tm_tag_macro_t}, }; static TMParserMapEntry map_SQL[] = { {'c', tm_tag_undef_t}, // cursor {'d', tm_tag_prototype_t}, // prototype {'f', tm_tag_function_t}, // function {'E', tm_tag_field_t}, // field {'l', tm_tag_undef_t}, // local {'L', tm_tag_undef_t}, // label {'P', tm_tag_package_t}, // package {'p', tm_tag_namespace_t}, // procedure {'r', tm_tag_undef_t}, // record {'s', tm_tag_undef_t}, // subtype {'t', tm_tag_class_t}, // table {'T', tm_tag_macro_t}, // trigger {'v', tm_tag_variable_t}, // variable {'i', tm_tag_struct_t}, // index {'e', tm_tag_undef_t}, // event {'U', tm_tag_undef_t}, // publication {'R', tm_tag_undef_t}, // service {'D', tm_tag_undef_t}, // domain {'V', tm_tag_member_t}, // view {'n', tm_tag_undef_t}, // synonym {'x', tm_tag_undef_t}, // mltable {'y', tm_tag_undef_t}, // mlconn {'z', tm_tag_undef_t}, // mlprop {'C', tm_tag_undef_t}, // ccflag }; static TMParserMapGroup group_SQL[] = { {N_("Functions"), TM_ICON_METHOD, tm_tag_function_t | tm_tag_prototype_t}, {N_("Procedures"), TM_ICON_NAMESPACE, tm_tag_namespace_t | tm_tag_package_t}, {N_("Indexes"), TM_ICON_STRUCT, tm_tag_struct_t}, {N_("Tables"), TM_ICON_CLASS, tm_tag_class_t}, {N_("Triggers"), TM_ICON_MACRO, tm_tag_macro_t}, {N_("Views"), TM_ICON_VAR, tm_tag_field_t | tm_tag_member_t}, {N_("Variables"), TM_ICON_VAR, tm_tag_variable_t}, }; static TMParserMapEntry map_DOCBOOK[] = { {'f', tm_tag_function_t}, {'c', tm_tag_class_t}, {'m', tm_tag_member_t}, {'d', tm_tag_macro_t}, {'v', tm_tag_variable_t}, {'s', tm_tag_struct_t}, }; static TMParserMapGroup group_DOCBOOK[] = { {N_("Chapter"), TM_ICON_NONE, tm_tag_function_t}, {N_("Section"), TM_ICON_NONE, tm_tag_class_t}, {N_("Sect1"), TM_ICON_NONE, tm_tag_member_t}, {N_("Sect2"), TM_ICON_NONE, tm_tag_macro_t}, {N_("Sect3"), TM_ICON_NONE, tm_tag_variable_t}, {N_("Appendix"), TM_ICON_NONE, tm_tag_struct_t}, }; // no scope information static TMParserMapEntry map_ERLANG[] = { {'d', tm_tag_macro_t}, // macro {'f', tm_tag_function_t}, // function {'m', tm_tag_undef_t}, // module {'r', tm_tag_struct_t}, // record {'t', tm_tag_typedef_t}, // type }; static TMParserMapGroup group_ERLANG[] = { {N_("Functions"), TM_ICON_METHOD, tm_tag_function_t}, {N_("Structs"), TM_ICON_STRUCT, tm_tag_struct_t}, {N_("Typedefs / Enums"), TM_ICON_STRUCT, tm_tag_typedef_t}, {N_("Macros"), TM_ICON_MACRO, tm_tag_macro_t}, }; // no scope information static TMParserMapEntry map_CSS[] = { {'c', tm_tag_class_t}, // class {'s', tm_tag_struct_t}, // selector {'i', tm_tag_variable_t}, // id }; static TMParserMapGroup group_CSS[] = { {N_("Classes"), TM_ICON_CLASS, tm_tag_class_t}, {N_("ID Selectors"), TM_ICON_VAR, tm_tag_variable_t}, {N_("Type Selectors"), TM_ICON_STRUCT, tm_tag_struct_t}, }; static TMParserMapEntry map_RUBY[] = { {'c', tm_tag_class_t}, // class {'f', tm_tag_method_t}, // method {'m', tm_tag_namespace_t}, // module {'S', tm_tag_member_t}, // singletonMethod {'C', tm_tag_undef_t}, // constant {'A', tm_tag_undef_t}, // accessor {'a', tm_tag_undef_t}, // alias {'L', tm_tag_undef_t}, // library }; static TMParserMapGroup group_RUBY[] = { {N_("Modules"), TM_ICON_NAMESPACE, tm_tag_namespace_t}, {N_("Classes"), TM_ICON_CLASS, tm_tag_class_t}, {N_("Singletons"), TM_ICON_STRUCT, tm_tag_member_t}, {N_("Methods"), TM_ICON_METHOD, tm_tag_method_t}, }; static TMParserMapEntry map_TCL[] = { {'p', tm_tag_function_t}, // procedure {'n', tm_tag_namespace_t}, // namespace {'z', tm_tag_undef_t}, // parameter }; static TMParserMapGroup group_TCL[] = { {N_("Namespaces"), TM_ICON_NAMESPACE, tm_tag_namespace_t}, {N_("Classes"), TM_ICON_CLASS, tm_tag_class_t}, {N_("Methods"), TM_ICON_METHOD, tm_tag_member_t}, {N_("Procedures"), TM_ICON_OTHER, tm_tag_function_t}, }; static TMParserMapEntry map_TCLOO[] = { {'c', tm_tag_class_t}, // class {'m', tm_tag_member_t}, // method }; #define group_TCLOO group_TCL static TMSubparserMapEntry subparser_TCLOO_TCL_map[] = { {tm_tag_namespace_t, tm_tag_namespace_t}, {tm_tag_class_t, tm_tag_class_t}, {tm_tag_member_t, tm_tag_member_t}, {tm_tag_function_t, tm_tag_function_t}, }; static TMParserMapEntry map_SH[] = { {'a', tm_tag_undef_t}, // alias {'f', tm_tag_function_t}, // function {'s', tm_tag_undef_t}, // script {'h', tm_tag_undef_t}, // heredoc }; static TMParserMapGroup group_SH[] = { {N_("Functions"), TM_ICON_METHOD, tm_tag_function_t}, }; static TMParserMapEntry map_D[] = { {'c', tm_tag_class_t}, // class {'e', tm_tag_enumerator_t}, // enumerator {'f', tm_tag_function_t}, // function {'g', tm_tag_enum_t}, // enum {'i', tm_tag_interface_t}, // interface {'m', tm_tag_member_t}, // member {'n', tm_tag_namespace_t}, // namespace {'p', tm_tag_prototype_t}, // prototype {'s', tm_tag_struct_t}, // struct {'t', tm_tag_typedef_t}, // typedef {'u', tm_tag_union_t}, // union {'v', tm_tag_variable_t}, // variable {'x', tm_tag_externvar_t}, // externvar }; static TMParserMapGroup group_D[] = { {N_("Module"), TM_ICON_NONE, tm_tag_namespace_t}, {N_("Classes"), TM_ICON_CLASS, tm_tag_class_t}, {N_("Interfaces"), TM_ICON_STRUCT, tm_tag_interface_t}, {N_("Functions"), TM_ICON_METHOD, tm_tag_function_t | tm_tag_prototype_t}, {N_("Members"), TM_ICON_MEMBER, tm_tag_member_t}, {N_("Structs"), TM_ICON_STRUCT, tm_tag_struct_t | tm_tag_union_t}, {N_("Typedefs / Enums"), TM_ICON_STRUCT, tm_tag_typedef_t | tm_tag_enum_t}, {N_("Variables"), TM_ICON_VAR, tm_tag_variable_t | tm_tag_enumerator_t}, {N_("Extern Variables"), TM_ICON_VAR, tm_tag_externvar_t}, }; static TMParserMapEntry map_DIFF[] = { {'m', tm_tag_function_t}, // modifiedFile {'n', tm_tag_function_t}, // newFile {'d', tm_tag_function_t}, // deletedFile {'h', tm_tag_undef_t}, // hunk }; static TMParserMapGroup group_DIFF[] = { {N_("Files"), TM_ICON_NONE, tm_tag_function_t}, }; static TMParserMapEntry map_VHDL[] = { {'c', tm_tag_variable_t}, // constant {'t', tm_tag_typedef_t}, // type {'T', tm_tag_typedef_t}, // subtype {'r', tm_tag_undef_t}, // record {'e', tm_tag_class_t}, // entity {'C', tm_tag_member_t}, // component {'d', tm_tag_undef_t}, // prototype {'f', tm_tag_function_t}, // function {'p', tm_tag_function_t}, // procedure {'P', tm_tag_namespace_t}, // package {'l', tm_tag_variable_t}, // local {'a', tm_tag_struct_t}, // architecture {'q', tm_tag_variable_t}, // port {'g', tm_tag_undef_t}, // generic {'s', tm_tag_variable_t}, // signal {'Q', tm_tag_member_t}, // process {'v', tm_tag_variable_t}, // variable {'A', tm_tag_typedef_t}, // alias }; static TMParserMapGroup group_VHDL[] = { {N_("Package"), TM_ICON_NAMESPACE, tm_tag_namespace_t}, {N_("Entities"), TM_ICON_CLASS, tm_tag_class_t}, {N_("Architectures"), TM_ICON_STRUCT, tm_tag_struct_t}, {N_("Types"), TM_ICON_OTHER, tm_tag_typedef_t}, {N_("Functions / Procedures"), TM_ICON_METHOD, tm_tag_function_t}, {N_("Variables / Signals / Ports"), TM_ICON_VAR, tm_tag_variable_t}, {N_("Processes / Blocks / Components"), TM_ICON_MEMBER, tm_tag_member_t}, }; static TMParserMapEntry map_LUA[] = { {'f', tm_tag_function_t}, // function {'X', tm_tag_undef_t}, // unknown }; static TMParserMapGroup group_LUA[] = { {N_("Functions"), TM_ICON_METHOD, tm_tag_function_t}, }; static TMParserMapEntry map_JAVASCRIPT[] = { {'f', tm_tag_function_t}, // function {'c', tm_tag_class_t}, // class {'m', tm_tag_method_t}, // method {'p', tm_tag_member_t}, // property {'C', tm_tag_macro_t}, // constant {'v', tm_tag_variable_t}, // variable {'g', tm_tag_function_t}, // generator {'G', tm_tag_undef_t}, // getter {'S', tm_tag_undef_t}, // setter {'M', tm_tag_undef_t}, // field }; static TMParserMapGroup group_JAVASCRIPT[] = { {N_("Classes"), TM_ICON_CLASS, tm_tag_class_t}, {N_("Functions"), TM_ICON_METHOD, tm_tag_function_t | tm_tag_method_t}, {N_("Members"), TM_ICON_MEMBER, tm_tag_member_t}, {N_("Macros"), TM_ICON_MACRO, tm_tag_macro_t}, {N_("Variables"), TM_ICON_VAR, tm_tag_variable_t}, }; // no scope information static TMParserMapEntry map_HASKELL[] = { {'t', tm_tag_typedef_t}, // type {'c', tm_tag_macro_t}, // constructor {'f', tm_tag_function_t}, // function {'m', tm_tag_namespace_t}, // module }; static TMParserMapGroup group_HASKELL[] = { {N_("Module"), TM_ICON_NONE, tm_tag_namespace_t}, {N_("Types"), TM_ICON_NONE, tm_tag_typedef_t}, {N_("Type constructors"), TM_ICON_NONE, tm_tag_macro_t}, {N_("Functions"), TM_ICON_METHOD, tm_tag_function_t}, }; #define map_UNUSED1 map_HASKELL #define group_UNUSED1 group_HASKELL static TMParserMapEntry map_CSHARP[] = { {'c', tm_tag_class_t}, // class {'d', tm_tag_macro_t}, // macro {'e', tm_tag_enumerator_t}, // enumerator {'E', tm_tag_undef_t}, // event {'f', tm_tag_field_t}, // field {'g', tm_tag_enum_t}, // enum {'i', tm_tag_interface_t}, // interface {'l', tm_tag_undef_t}, // local {'m', tm_tag_method_t}, // method {'n', tm_tag_namespace_t}, // namespace {'p', tm_tag_undef_t}, // property {'s', tm_tag_struct_t}, // struct {'t', tm_tag_typedef_t}, // typedef }; #define group_CSHARP group_C // no scope information static TMParserMapEntry map_FREEBASIC[] = { {'c', tm_tag_macro_t}, // constant {'f', tm_tag_function_t}, // function {'l', tm_tag_namespace_t}, // label {'t', tm_tag_struct_t}, // type {'v', tm_tag_variable_t}, // variable {'g', tm_tag_externvar_t}, // enum }; static TMParserMapGroup group_FREEBASIC[] = { {N_("Functions"), TM_ICON_METHOD, tm_tag_function_t}, {N_("Variables"), TM_ICON_VAR, tm_tag_variable_t | tm_tag_externvar_t}, {N_("Constants"), TM_ICON_MACRO, tm_tag_macro_t}, {N_("Types"), TM_ICON_NAMESPACE, tm_tag_struct_t}, {N_("Labels"), TM_ICON_MEMBER, tm_tag_namespace_t}, }; // no scope information static TMParserMapEntry map_HAXE[] = { {'m', tm_tag_method_t}, // method {'c', tm_tag_class_t}, // class {'e', tm_tag_enum_t}, // enum {'v', tm_tag_variable_t}, // variable {'i', tm_tag_interface_t}, // interface {'t', tm_tag_typedef_t}, // typedef }; static TMParserMapGroup group_HAXE[] = { {N_("Interfaces"), TM_ICON_STRUCT, tm_tag_interface_t}, {N_("Classes"), TM_ICON_CLASS, tm_tag_class_t}, {N_("Methods"), TM_ICON_METHOD, tm_tag_method_t}, {N_("Types"), TM_ICON_MACRO, tm_tag_typedef_t | tm_tag_enum_t}, {N_("Variables"), TM_ICON_VAR, tm_tag_variable_t}, }; static TMParserMapEntry map_REST[] = { {'c', tm_tag_namespace_t}, // chapter {'s', tm_tag_member_t}, // section {'S', tm_tag_macro_t}, // subsection {'t', tm_tag_variable_t}, // subsubsection {'C', tm_tag_undef_t}, // citation {'T', tm_tag_undef_t}, // target {'d', tm_tag_undef_t}, // substdef }; static TMParserMapGroup group_REST[] = { {N_("Chapter"), TM_ICON_NONE, tm_tag_namespace_t}, {N_("Section"), TM_ICON_NONE, tm_tag_member_t}, {N_("Subsection"), TM_ICON_NONE, tm_tag_macro_t}, {N_("Subsubsection"), TM_ICON_NONE, tm_tag_variable_t}, }; // no scope information static TMParserMapEntry map_HTML[] = { {'a', tm_tag_member_t}, // anchor {'c', tm_tag_undef_t}, // class {'h', tm_tag_namespace_t}, // heading1 {'i', tm_tag_class_t}, // heading2 {'j', tm_tag_variable_t}, // heading3 {'C', tm_tag_undef_t}, // stylesheet {'I', tm_tag_undef_t}, // id {'J', tm_tag_undef_t}, // script }; static TMParserMapGroup group_HTML[] = { {N_("Functions"), TM_ICON_NONE, tm_tag_function_t}, // javascript functions from subparser {N_("Anchors"), TM_ICON_NONE, tm_tag_member_t}, {N_("H1 Headings"), TM_ICON_NONE, tm_tag_namespace_t}, {N_("H2 Headings"), TM_ICON_NONE, tm_tag_class_t}, {N_("H3 Headings"), TM_ICON_NONE, tm_tag_variable_t}, }; static TMSubparserMapEntry subparser_HTML_javascript_map[] = { {tm_tag_function_t, tm_tag_function_t}, }; static TMParserMapEntry map_FORTRAN[] = { {'b', tm_tag_undef_t}, // blockData {'c', tm_tag_macro_t}, // common {'e', tm_tag_undef_t}, // entry {'E', tm_tag_enum_t}, // enum {'f', tm_tag_function_t}, // function {'i', tm_tag_interface_t}, // interface {'k', tm_tag_member_t}, // component {'l', tm_tag_undef_t}, // label {'L', tm_tag_undef_t}, // local {'m', tm_tag_namespace_t}, // module {'M', tm_tag_member_t}, // method {'n', tm_tag_undef_t}, // namelist {'N', tm_tag_enumerator_t}, // enumerator {'p', tm_tag_struct_t}, // program {'P', tm_tag_undef_t}, // prototype {'s', tm_tag_method_t}, // subroutine {'t', tm_tag_class_t}, // type {'v', tm_tag_variable_t}, // variable {'S', tm_tag_undef_t}, // submodule }; static TMParserMapGroup group_FORTRAN[] = { {N_("Module"), TM_ICON_CLASS, tm_tag_namespace_t}, {N_("Programs"), TM_ICON_CLASS, tm_tag_struct_t}, {N_("Interfaces"), TM_ICON_STRUCT, tm_tag_interface_t}, {N_("Functions / Subroutines"), TM_ICON_METHOD, tm_tag_function_t | tm_tag_method_t}, {N_("Variables"), TM_ICON_VAR, tm_tag_variable_t | tm_tag_enumerator_t}, {N_("Types"), TM_ICON_CLASS, tm_tag_class_t}, {N_("Components"), TM_ICON_MEMBER, tm_tag_member_t}, {N_("Blocks"), TM_ICON_MEMBER, tm_tag_macro_t}, {N_("Enums"), TM_ICON_STRUCT, tm_tag_enum_t}, }; static TMParserMapEntry map_MATLAB[] = { {'f', tm_tag_function_t}, // function {'s', tm_tag_struct_t}, // struct }; static TMParserMapGroup group_MATLAB[] = { {N_("Functions"), TM_ICON_METHOD, tm_tag_function_t}, {N_("Structures"), TM_ICON_STRUCT, tm_tag_struct_t}, }; #define map_CUDA map_C #define group_CUDA group_C static TMParserMapEntry map_VALA[] = { {'c', tm_tag_class_t}, // class {'d', tm_tag_macro_t}, // macro {'e', tm_tag_enumerator_t}, // enumerator {'f', tm_tag_field_t}, // field {'g', tm_tag_enum_t}, // enum {'i', tm_tag_interface_t}, // interface {'l', tm_tag_undef_t}, // local {'m', tm_tag_method_t}, // method {'n', tm_tag_namespace_t}, // namespace {'p', tm_tag_undef_t}, // property {'S', tm_tag_undef_t}, // signal {'s', tm_tag_struct_t}, // struct }; #define group_VALA group_C static TMParserMapEntry map_ACTIONSCRIPT[] = { {'f', tm_tag_function_t}, // function {'c', tm_tag_class_t}, // class {'i', tm_tag_interface_t}, // interface {'P', tm_tag_package_t}, // package {'m', tm_tag_method_t}, // method {'p', tm_tag_member_t}, // property {'v', tm_tag_variable_t}, // variable {'l', tm_tag_variable_t}, // localvar {'C', tm_tag_macro_t}, // constant {'I', tm_tag_externvar_t}, // import {'x', tm_tag_other_t}, // mxtag }; static TMParserMapGroup group_ACTIONSCRIPT[] = { {N_("Imports"), TM_ICON_NAMESPACE, tm_tag_externvar_t}, {N_("Package"), TM_ICON_NAMESPACE, tm_tag_package_t}, {N_("Interfaces"), TM_ICON_STRUCT, tm_tag_interface_t}, {N_("Classes"), TM_ICON_CLASS, tm_tag_class_t}, {N_("Functions"), TM_ICON_METHOD, tm_tag_function_t| tm_tag_method_t}, {N_("Properties"), TM_ICON_MEMBER, tm_tag_member_t}, {N_("Variables"), TM_ICON_VAR, tm_tag_variable_t}, {N_("Constants"), TM_ICON_MACRO, tm_tag_macro_t}, {N_("Other"), TM_ICON_OTHER, tm_tag_other_t}, }; static TMParserMapEntry map_NSIS[] = { {'s', tm_tag_namespace_t}, // section {'f', tm_tag_function_t}, // function {'v', tm_tag_variable_t}, // variable {'d', tm_tag_undef_t}, // definition {'m', tm_tag_undef_t}, // macro {'S', tm_tag_undef_t}, // sectionGroup {'p', tm_tag_undef_t}, // macroparam {'l', tm_tag_undef_t}, // langstr {'i', tm_tag_undef_t}, // script }; static TMParserMapGroup group_NSIS[] = { {N_("Sections"), TM_ICON_OTHER, tm_tag_namespace_t}, {N_("Functions"), TM_ICON_METHOD, tm_tag_function_t}, {N_("Variables"), TM_ICON_VAR, tm_tag_variable_t}, }; static TMParserMapEntry map_MARKDOWN[] = { {'c', tm_tag_namespace_t}, //chapter {'s', tm_tag_member_t}, //section {'S', tm_tag_macro_t}, //subsection {'t', tm_tag_variable_t}, //subsubsection {'T', tm_tag_struct_t}, //l4subsection {'u', tm_tag_union_t}, //l5subsection {'n', tm_tag_undef_t}, //footnote }; static TMParserMapGroup group_MARKDOWN[] = { {N_("Chapters"), TM_ICON_NONE, tm_tag_namespace_t}, {N_("Sections"), TM_ICON_NONE, tm_tag_member_t}, {N_("Subsections"), TM_ICON_NONE, tm_tag_macro_t}, {N_("Subsubsections"), TM_ICON_NONE, tm_tag_variable_t}, {N_("Level 4 sections"), TM_ICON_NONE, tm_tag_struct_t}, {N_("Level 5 sections"), TM_ICON_NONE, tm_tag_union_t}, }; static TMParserMapEntry map_TXT2TAGS[] = { {'s', tm_tag_member_t}, // section }; #define group_TXT2TAGS group_REST // no scope information static TMParserMapEntry map_ABC[] = { {'s', tm_tag_member_t}, // section }; #define group_ABC group_REST static TMParserMapEntry map_VERILOG[] = { {'c', tm_tag_variable_t}, // constant {'e', tm_tag_typedef_t}, // event {'f', tm_tag_function_t}, // function {'m', tm_tag_class_t}, // module {'n', tm_tag_variable_t}, // net {'p', tm_tag_variable_t}, // port {'r', tm_tag_variable_t}, // register {'t', tm_tag_function_t}, // task {'b', tm_tag_undef_t}, // block {'i', tm_tag_undef_t}, // instance }; static TMParserMapGroup group_VERILOG[] = { {N_("Events"), TM_ICON_MACRO, tm_tag_typedef_t}, {N_("Modules"), TM_ICON_CLASS, tm_tag_class_t}, {N_("Functions / Tasks"), TM_ICON_METHOD, tm_tag_function_t}, {N_("Variables"), TM_ICON_VAR, tm_tag_variable_t}, }; static TMParserMapEntry map_R[] = { {'f', tm_tag_function_t}, // function {'l', tm_tag_other_t}, // library {'s', tm_tag_other_t}, // source {'g', tm_tag_undef_t}, // globalVar {'v', tm_tag_undef_t}, // functionVar {'z', tm_tag_undef_t}, // parameter {'c', tm_tag_undef_t}, // vector {'L', tm_tag_undef_t}, // list {'d', tm_tag_undef_t}, // dataframe {'n', tm_tag_undef_t}, // nameattr }; static TMParserMapGroup group_R[] = { {N_("Functions"), TM_ICON_METHOD, tm_tag_function_t}, {N_("Other"), TM_ICON_NONE, tm_tag_other_t}, }; static TMParserMapEntry map_COBOL[] = { {'f', tm_tag_function_t}, // fd {'g', tm_tag_struct_t}, // group {'P', tm_tag_class_t}, // program {'s', tm_tag_namespace_t}, // section {'D', tm_tag_interface_t}, // division {'p', tm_tag_macro_t}, // paragraph {'d', tm_tag_variable_t}, // data {'S', tm_tag_externvar_t}, // sourcefile }; static TMParserMapGroup group_COBOL[] = { {N_("Program"), TM_ICON_CLASS, tm_tag_class_t}, {N_("File"), TM_ICON_METHOD, tm_tag_function_t}, {N_("Divisions"), TM_ICON_NAMESPACE, tm_tag_interface_t}, {N_("Sections"), TM_ICON_NAMESPACE, tm_tag_namespace_t}, {N_("Paragraph"), TM_ICON_OTHER, tm_tag_macro_t}, {N_("Group"), TM_ICON_STRUCT, tm_tag_struct_t}, {N_("Data"), TM_ICON_VAR, tm_tag_variable_t}, {N_("Copies"), TM_ICON_NAMESPACE, tm_tag_externvar_t}, }; static TMParserMapEntry map_OBJC[] = { {'i', tm_tag_interface_t}, // interface {'I', tm_tag_undef_t}, // implementation {'P', tm_tag_undef_t}, // protocol {'m', tm_tag_method_t}, // method {'c', tm_tag_class_t}, // class {'v', tm_tag_variable_t}, // var {'E', tm_tag_field_t}, // field {'f', tm_tag_function_t}, // function {'p', tm_tag_undef_t}, // property {'t', tm_tag_typedef_t}, // typedef {'s', tm_tag_struct_t}, // struct {'e', tm_tag_enum_t}, // enum {'M', tm_tag_macro_t}, // macro {'C', tm_tag_undef_t}, // category }; #define group_OBJC group_C static TMParserMapEntry map_ASCIIDOC[] = { {'c', tm_tag_namespace_t}, //chapter {'s', tm_tag_member_t}, //section {'S', tm_tag_macro_t}, //subsection {'t', tm_tag_variable_t}, //subsubsection {'T', tm_tag_struct_t}, //l4subsection {'u', tm_tag_enumerator_t}, //l5subsection {'a', tm_tag_undef_t}, //anchor }; static TMParserMapGroup group_ASCIIDOC[] = { {N_("Document"), TM_ICON_NONE, tm_tag_namespace_t}, {N_("Section Level 1"), TM_ICON_NONE, tm_tag_member_t}, {N_("Section Level 2"), TM_ICON_NONE, tm_tag_macro_t}, {N_("Section Level 3"), TM_ICON_NONE, tm_tag_variable_t}, {N_("Section Level 4"), TM_ICON_NONE, tm_tag_struct_t}, {N_("Section Level 5"), TM_ICON_NONE, tm_tag_enumerator_t}, }; // no scope information static TMParserMapEntry map_ABAQUS[] = { {'p', tm_tag_class_t}, // part {'a', tm_tag_member_t}, // assembly {'s', tm_tag_interface_t}, // step }; static TMParserMapGroup group_ABAQUS[] = { {N_("Parts"), TM_ICON_NONE, tm_tag_class_t}, {N_("Assembly"), TM_ICON_NONE, tm_tag_member_t}, {N_("Steps"), TM_ICON_NONE, tm_tag_interface_t}, }; static TMParserMapEntry map_RUST[] = { {'n', tm_tag_namespace_t}, // module {'s', tm_tag_struct_t}, // struct {'i', tm_tag_interface_t}, // interface {'c', tm_tag_class_t}, // implementation {'f', tm_tag_function_t}, // function {'g', tm_tag_enum_t}, // enum {'t', tm_tag_typedef_t}, // typedef {'v', tm_tag_variable_t}, // variable {'M', tm_tag_macro_t}, // macro {'m', tm_tag_field_t}, // field {'e', tm_tag_enumerator_t}, // enumerator {'P', tm_tag_method_t}, // method }; static TMParserMapGroup group_RUST[] = { {N_("Modules"), TM_ICON_NAMESPACE, tm_tag_namespace_t}, {N_("Structures"), TM_ICON_STRUCT, tm_tag_struct_t}, {N_("Traits"), TM_ICON_CLASS, tm_tag_interface_t}, {N_("Implementations"), TM_ICON_CLASS, tm_tag_class_t}, {N_("Functions"), TM_ICON_METHOD, tm_tag_function_t | tm_tag_method_t}, {N_("Typedefs / Enums"), TM_ICON_STRUCT, tm_tag_typedef_t | tm_tag_enum_t}, {N_("Variables"), TM_ICON_VAR, tm_tag_variable_t | tm_tag_enumerator_t}, {N_("Macros"), TM_ICON_MACRO, tm_tag_macro_t}, {N_("Methods"), TM_ICON_MEMBER, tm_tag_field_t}, }; static TMParserMapEntry map_GO[] = { {'p', tm_tag_namespace_t}, // package {'f', tm_tag_function_t}, // func {'c', tm_tag_macro_t}, // const {'t', tm_tag_typedef_t}, // type {'v', tm_tag_variable_t}, // var {'s', tm_tag_struct_t}, // struct {'i', tm_tag_interface_t}, // interface {'m', tm_tag_member_t}, // member {'M', tm_tag_undef_t}, // anonMember {'n', tm_tag_undef_t}, // methodSpec {'u', tm_tag_undef_t}, // unknown {'P', tm_tag_undef_t}, // packageName {'a', tm_tag_undef_t}, // talias {'R', tm_tag_undef_t}, // receiver }; static TMParserMapGroup group_GO[] = { {N_("Package"), TM_ICON_NAMESPACE, tm_tag_namespace_t}, {N_("Functions"), TM_ICON_METHOD, tm_tag_function_t}, {N_("Interfaces"), TM_ICON_STRUCT, tm_tag_interface_t}, {N_("Structs"), TM_ICON_STRUCT, tm_tag_struct_t}, {N_("Types"), TM_ICON_STRUCT, tm_tag_typedef_t}, {N_("Constants"), TM_ICON_MACRO, tm_tag_macro_t}, {N_("Variables"), TM_ICON_VAR, tm_tag_variable_t}, {N_("Members"), TM_ICON_MEMBER, tm_tag_member_t}, }; static TMParserMapEntry map_JSON[] = { {'o', tm_tag_member_t}, // object {'a', tm_tag_member_t}, // array {'n', tm_tag_member_t}, // number {'s', tm_tag_member_t}, // string {'b', tm_tag_member_t}, // boolean {'z', tm_tag_member_t}, // null }; static TMParserMapGroup group_JSON[] = { {N_("Members"), TM_ICON_MEMBER, tm_tag_member_t}, }; /* Zephir, same as PHP */ #define map_ZEPHIR map_PHP #define group_ZEPHIR group_PHP static TMParserMapEntry map_POWERSHELL[] = { {'f', tm_tag_function_t}, // function {'v', tm_tag_variable_t}, // variable }; static TMParserMapGroup group_POWERSHELL[] = { {N_("Functions"), TM_ICON_METHOD, tm_tag_function_t}, {N_("Variables"), TM_ICON_VAR, tm_tag_variable_t}, }; static TMParserMapEntry map_JULIA[] = { {'c', tm_tag_variable_t}, // constant {'f', tm_tag_function_t}, // function {'g', tm_tag_member_t}, // field {'m', tm_tag_macro_t}, // macro {'n', tm_tag_namespace_t}, // module {'s', tm_tag_struct_t}, // struct {'t', tm_tag_typedef_t}, // type /* defined as externvar to get those excluded as forward type in symbols.c:goto_tag() * so we can jump to the real implementation (if known) instead of to the import statement */ {'x', tm_tag_externvar_t}, // unknown }; static TMParserMapGroup group_JULIA[] = { {N_("Constants"), TM_ICON_VAR, tm_tag_variable_t}, {N_("Modules"), TM_ICON_NAMESPACE, tm_tag_namespace_t}, {N_("Functions"), TM_ICON_METHOD, tm_tag_function_t}, {N_("Fields"), TM_ICON_MEMBER, tm_tag_member_t}, {N_("Macros"), TM_ICON_MACRO, tm_tag_macro_t}, {N_("Structures"), TM_ICON_STRUCT, tm_tag_struct_t}, {N_("Types"), TM_ICON_CLASS, tm_tag_typedef_t}, {N_("Unknowns"), TM_ICON_OTHER, tm_tag_externvar_t}, }; static TMParserMapEntry map_CPREPROCESSOR[] = { {'d', tm_tag_undef_t}, // macro {'h', tm_tag_undef_t}, // header {'D', tm_tag_undef_t}, // parameter }; #define group_CPREPROCESSOR group_C static TMParserMapEntry map_GDSCRIPT[] = { {'c', tm_tag_class_t}, // class {'m', tm_tag_method_t}, // method {'v', tm_tag_variable_t}, // variable {'C', tm_tag_variable_t}, // const {'g', tm_tag_enum_t}, // enum {'e', tm_tag_variable_t}, // enumerator {'z', tm_tag_local_var_t}, // parameter {'l', tm_tag_local_var_t}, // local {'s', tm_tag_variable_t}, // signal }; static TMParserMapGroup group_GDSCRIPT[] = { {N_("Classes"), TM_ICON_CLASS, tm_tag_class_t}, {N_("Methods"), TM_ICON_MACRO, tm_tag_method_t}, {N_("Variables"), TM_ICON_VAR, tm_tag_variable_t | tm_tag_local_var_t}, {N_("Enums"), TM_ICON_STRUCT, tm_tag_enum_t}, }; static TMParserMapEntry map_CLOJURE[] = { {'f', tm_tag_function_t}, // function {'n', tm_tag_namespace_t}, // namespace }; static TMParserMapGroup group_CLOJURE[] = { {N_("Namespaces"), TM_ICON_NAMESPACE, tm_tag_namespace_t}, {N_("Functions"), TM_ICON_METHOD, tm_tag_function_t}, }; static TMParserMapEntry map_LISP[] = { {'u', tm_tag_undef_t}, // unknown {'f', tm_tag_function_t}, // function {'v', tm_tag_variable_t}, // variable {'m', tm_tag_macro_t}, // macro {'c', tm_tag_field_t}, // const }; static TMParserMapGroup group_LISP[] = { {N_("Functions"), TM_ICON_METHOD, tm_tag_function_t}, {N_("Macros"), TM_ICON_MACRO, tm_tag_macro_t}, {N_("Variables"), TM_ICON_VAR, tm_tag_variable_t}, {N_("Constants"), TM_ICON_VAR, tm_tag_field_t}, }; static TMParserMapEntry map_TYPESCRIPT[] = { {'f', tm_tag_function_t}, // function {'c', tm_tag_class_t}, // class {'i', tm_tag_interface_t}, // interface {'g', tm_tag_enum_t}, // enum {'e', tm_tag_enumerator_t}, // enumerator {'m', tm_tag_method_t}, // method {'n', tm_tag_namespace_t}, // namespace {'z', tm_tag_local_var_t}, // parameter {'p', tm_tag_member_t}, // property {'v', tm_tag_variable_t}, // variable {'l', tm_tag_local_var_t}, // local {'C', tm_tag_macro_t}, // constant {'G', tm_tag_undef_t}, // generator {'a', tm_tag_undef_t}, // alias }; static TMParserMapGroup group_TYPESCRIPT[] = { {N_("Namespaces"), TM_ICON_NAMESPACE, tm_tag_namespace_t}, {N_("Classes"), TM_ICON_CLASS, tm_tag_class_t}, {N_("Interfaces"), TM_ICON_STRUCT, tm_tag_interface_t}, {N_("Functions"), TM_ICON_METHOD, tm_tag_function_t | tm_tag_method_t}, {N_("Enums"), TM_ICON_STRUCT, tm_tag_enum_t}, {N_("Variables"), TM_ICON_VAR, tm_tag_variable_t | tm_tag_local_var_t}, {N_("Constants"), TM_ICON_MACRO, tm_tag_macro_t}, {N_("Other"), TM_ICON_MEMBER, tm_tag_member_t | tm_tag_enumerator_t}, }; static TMParserMapEntry map_ADA[] = { {'P', tm_tag_package_t}, // packspec {'p', tm_tag_package_t}, // package {'T', tm_tag_typedef_t}, // typespec {'t', tm_tag_typedef_t}, // type {'U', tm_tag_undef_t}, // subspec {'u', tm_tag_typedef_t}, // subtype {'c', tm_tag_member_t}, // component {'l', tm_tag_enumerator_t}, // literal {'V', tm_tag_undef_t}, // varspec {'v', tm_tag_variable_t}, // variable {'f', tm_tag_undef_t}, // formal {'n', tm_tag_macro_t}, // constant {'x', tm_tag_undef_t}, // exception {'R', tm_tag_prototype_t}, // subprogspec {'r', tm_tag_function_t}, // subprogram {'K', tm_tag_prototype_t}, // taskspec {'k', tm_tag_method_t}, // task {'O', tm_tag_undef_t}, // protectspec {'o', tm_tag_undef_t}, // protected {'E', tm_tag_undef_t}, // entryspec {'e', tm_tag_undef_t}, // entry {'b', tm_tag_undef_t}, // label {'i', tm_tag_undef_t}, // identifier {'a', tm_tag_undef_t}, // autovar {'y', tm_tag_undef_t}, // anon }; static TMParserMapGroup group_ADA[] = { {N_("Packages"), TM_ICON_NAMESPACE, tm_tag_package_t}, {N_("Types"), TM_ICON_STRUCT, tm_tag_typedef_t}, {N_("Functions"), TM_ICON_METHOD, tm_tag_function_t | tm_tag_prototype_t}, {N_("Tasks"), TM_ICON_METHOD, tm_tag_method_t}, {N_("Variables"), TM_ICON_VAR, tm_tag_variable_t}, {N_("Constants"), TM_ICON_MACRO, tm_tag_macro_t}, {N_("Other"), TM_ICON_MEMBER, tm_tag_member_t | tm_tag_enumerator_t}, }; static TMParserMapEntry map_BATCH[] = { {'l', tm_tag_other_t}, // label {'v', tm_tag_variable_t}, // variable }; static TMParserMapGroup group_BATCH[] = { {N_("Labels"), TM_ICON_OTHER, tm_tag_other_t}, {N_("Variables"), TM_ICON_VAR, tm_tag_variable_t}, }; static TMParserMapEntry map_AUTOIT[] = { {'f', tm_tag_function_t}, {'r', tm_tag_other_t}, {'g', tm_tag_variable_t}, {'l', tm_tag_variable_t}, {'S', tm_tag_undef_t}, }; static TMParserMapGroup group_AUTOIT[] = { {N_("Functions"), TM_ICON_METHOD, tm_tag_function_t}, {N_("Regions"), TM_ICON_OTHER, tm_tag_other_t}, {N_("Variables"), TM_ICON_VAR, tm_tag_variable_t}, }; typedef struct { TMParserMapEntry *entries; guint size; TMParserMapGroup *groups; guint group_num; } TMParserMap; #define MAP_ENTRY(lang) [TM_PARSER_##lang] = {map_##lang, G_N_ELEMENTS(map_##lang), group_##lang, G_N_ELEMENTS(group_##lang)} /* keep in sync with TM_PARSER_* definitions in the header */ static TMParserMap parser_map[] = { MAP_ENTRY(C), MAP_ENTRY(CPP), MAP_ENTRY(JAVA), MAP_ENTRY(MAKEFILE), MAP_ENTRY(PASCAL), MAP_ENTRY(PERL), MAP_ENTRY(PHP), MAP_ENTRY(PYTHON), MAP_ENTRY(LATEX), MAP_ENTRY(BIBTEX), MAP_ENTRY(ASM), MAP_ENTRY(CONF), MAP_ENTRY(SQL), MAP_ENTRY(DOCBOOK), MAP_ENTRY(ERLANG), MAP_ENTRY(CSS), MAP_ENTRY(RUBY), MAP_ENTRY(TCL), MAP_ENTRY(SH), MAP_ENTRY(D), MAP_ENTRY(FORTRAN), MAP_ENTRY(GDSCRIPT), MAP_ENTRY(DIFF), MAP_ENTRY(VHDL), MAP_ENTRY(LUA), MAP_ENTRY(JAVASCRIPT), MAP_ENTRY(HASKELL), MAP_ENTRY(CSHARP), MAP_ENTRY(FREEBASIC), MAP_ENTRY(HAXE), MAP_ENTRY(REST), MAP_ENTRY(HTML), MAP_ENTRY(ADA), MAP_ENTRY(CUDA), MAP_ENTRY(MATLAB), MAP_ENTRY(VALA), MAP_ENTRY(ACTIONSCRIPT), MAP_ENTRY(NSIS), MAP_ENTRY(MARKDOWN), MAP_ENTRY(TXT2TAGS), MAP_ENTRY(ABC), MAP_ENTRY(VERILOG), MAP_ENTRY(R), MAP_ENTRY(COBOL), MAP_ENTRY(OBJC), MAP_ENTRY(ASCIIDOC), MAP_ENTRY(ABAQUS), MAP_ENTRY(RUST), MAP_ENTRY(GO), MAP_ENTRY(JSON), MAP_ENTRY(ZEPHIR), MAP_ENTRY(POWERSHELL), MAP_ENTRY(JULIA), MAP_ENTRY(CPREPROCESSOR), MAP_ENTRY(TCLOO), MAP_ENTRY(CLOJURE), MAP_ENTRY(LISP), MAP_ENTRY(TYPESCRIPT), MAP_ENTRY(BATCH), MAP_ENTRY(AUTOIT), }; /* make sure the parser map is consistent and complete */ G_STATIC_ASSERT(G_N_ELEMENTS(parser_map) == TM_PARSER_COUNT); TMTagType tm_parser_get_tag_type(gchar kind, TMParserType lang) { TMParserMap *map = &parser_map[lang]; guint i; for (i = 0; i < map->size; i++) { TMParserMapEntry *entry = &map->entries[i]; if (entry->kind == kind) return entry->type; } return tm_tag_undef_t; } gchar tm_parser_get_tag_kind(TMTagType type, TMParserType lang) { TMParserMap *map = &parser_map[lang]; guint i; for (i = 0; i < map->size; i++) { TMParserMapEntry *entry = &map->entries[i]; if (entry->type == type) return entry->kind; } return '\0'; } gint tm_parser_get_sidebar_group(TMParserType lang, TMTagType type) { TMParserMap *map; guint i; if (lang >= TM_PARSER_COUNT) return -1; map = &parser_map[lang]; for (i = 0; i < map->group_num; i++) { if (map->groups[i].types & type) return i + 1; // "Symbols" group is always first } return -1; } const gchar *tm_parser_get_sidebar_info(TMParserType lang, gint group, guint *icon) { const gchar *name; TMParserMap *map; TMParserMapGroup *grp; if (lang >= TM_PARSER_COUNT) return NULL; if (group == 0) { name = _("Symbols"); *icon = TM_ICON_NAMESPACE; } else { map = &parser_map[lang]; if (group > (gint)map->group_num) return NULL; grp = &map->groups[group - 1]; name = _(grp->name); *icon = grp->icon; } return name; } static void add_subparser(TMParserType lang, TMParserType sublang, TMSubparserMapEntry *map, guint map_size) { guint i; GPtrArray *mapping; GHashTable *lang_map = g_hash_table_lookup(subparser_map, GINT_TO_POINTER(lang)); if (!lang_map) { lang_map = g_hash_table_new(g_direct_hash, g_direct_equal); g_hash_table_insert(subparser_map, GINT_TO_POINTER(lang), lang_map); } mapping = g_ptr_array_new(); for (i = 0; i < map_size; i++) g_ptr_array_add(mapping, &map[i]); g_hash_table_insert(lang_map, GINT_TO_POINTER(sublang), mapping); } #define SUBPARSER_MAP_ENTRY(lang, sublang, map) add_subparser(TM_PARSER_##lang, TM_PARSER_##sublang, map, G_N_ELEMENTS(map)) static void init_subparser_map(void) { SUBPARSER_MAP_ENTRY(HTML, JAVASCRIPT, subparser_HTML_javascript_map); SUBPARSER_MAP_ENTRY(TCLOO, TCL, subparser_TCLOO_TCL_map); } TMTagType tm_parser_get_subparser_type(TMParserType lang, TMParserType sublang, TMTagType type) { guint i; GHashTable *lang_map; GPtrArray *mapping; if (!subparser_map) { subparser_map = g_hash_table_new(g_direct_hash, g_direct_equal); init_subparser_map(); } lang_map = g_hash_table_lookup(subparser_map, GINT_TO_POINTER(lang)); if (!lang_map) return tm_tag_undef_t; mapping = g_hash_table_lookup(lang_map, GINT_TO_POINTER(sublang)); if (!mapping) return tm_tag_undef_t; for (i = 0; i < mapping->len; i++) { TMSubparserMapEntry *entry = mapping->pdata[i]; if (entry->orig_type == type) return entry->new_type; } return tm_tag_undef_t; } void tm_parser_verify_type_mappings(void) { TMParserType lang; if (TM_PARSER_COUNT > tm_ctags_get_lang_count()) g_error("More parsers defined in Geany than in ctags"); for (lang = 0; lang < TM_PARSER_COUNT; lang++) { const gchar *kinds = tm_ctags_get_lang_kinds(lang); TMParserMap *map = &parser_map[lang]; gchar presence_map[256]; TMTagType lang_types = 0; TMTagType group_types = 0; guint i; if (! map->entries || map->size < 1) g_error("No tag types in TM for %s, is the language listed in parser_map?", tm_ctags_get_lang_name(lang)); if (map->size != strlen(kinds)) g_error("Different number of tag types in TM (%d) and ctags (%d) for %s", map->size, (int)strlen(kinds), tm_ctags_get_lang_name(lang)); memset(presence_map, 0, sizeof(presence_map)); for (i = 0; i < map->size; i++) { gboolean ctags_found = FALSE; gboolean tm_found = FALSE; guint j; for (j = 0; j < map->size; j++) { /* check that for every type in TM there's a type in ctags */ if (map->entries[i].kind == kinds[j]) ctags_found = TRUE; /* check that for every type in ctags there's a type in TM */ if (map->entries[j].kind == kinds[i]) tm_found = TRUE; if (ctags_found && tm_found) break; } if (!ctags_found) g_error("Tag type '%c' found in TM but not in ctags for %s", map->entries[i].kind, tm_ctags_get_lang_name(lang)); if (!tm_found) g_error("Tag type '%c' found in ctags but not in TM for %s", kinds[i], tm_ctags_get_lang_name(lang)); presence_map[(unsigned char) map->entries[i].kind]++; lang_types |= map->entries[i].type; } for (i = 0; i < sizeof(presence_map); i++) { if (presence_map[i] > 1) g_error("Duplicate tag type '%c' found for %s", (gchar)i, tm_ctags_get_lang_name(lang)); } for (i = 0; i < map->group_num; i++) group_types |= map->groups[i].types; if ((group_types & lang_types) != lang_types) g_warning("Not all tag types mapped to symbol tree groups for %s", tm_ctags_get_lang_name(lang)); } } /* When the suffix of 'str' is an operator that should trigger scope * autocompletion, this function should return the length of the operator, * zero otherwise. */ gint tm_parser_scope_autocomplete_suffix(TMParserType lang, const gchar *str) { const gchar *sep = tm_parser_scope_separator(lang); if (g_str_has_suffix(str, sep)) return strlen(sep); switch (lang) { case TM_PARSER_C: case TM_PARSER_CPP: if (g_str_has_suffix(str, ".")) return 1; else if (g_str_has_suffix(str, "->")) return 2; else if (lang == TM_PARSER_CPP && g_str_has_suffix(str, "->*")) return 3; default: break; } return 0; } /* Get the name of constructor method. Arguments of this method will be used * for calltips when creating an object using the class name * (e.g. after the opening brace in 'c = MyClass()' in Python) */ const gchar *tm_parser_get_constructor_method(TMParserType lang) { switch (lang) { case TM_PARSER_D: return "this"; case TM_PARSER_PYTHON: return "__init__"; default: return NULL; } } /* determine anonymous tags from tag names only when corresponding * ctags information is not available */ gboolean tm_parser_is_anon_name(TMParserType lang, const gchar *name) { guint i; char dummy; if (sscanf(name, "__anon%u%c", &i, &dummy) == 1) /* uctags tags files */ return TRUE; else if (lang == TM_PARSER_C || lang == TM_PARSER_CPP) /* legacy Geany tags files */ return sscanf(name, "anon_%*[a-z]_%u%c", &i, &dummy) == 1; else if (lang == TM_PARSER_FORTRAN) /* legacy Geany tags files */ { return sscanf(name, "Structure#%u%c", &i, &dummy) == 1 || sscanf(name, "Interface#%u%c", &i, &dummy) == 1 || sscanf(name, "Enum#%u%c", &i, &dummy) == 1; } return FALSE; } static gchar *replace_string_if_present(gchar *haystack, const gchar *needle, const gchar *subst) { if (strstr(haystack, needle)) { gchar **split = g_strsplit(haystack, needle, -1); gchar *ret = g_strjoinv(subst, split); g_strfreev(split); return ret; } return haystack; } /* return updated scope or original scope if no change needed */ gchar *tm_parser_update_scope(TMParserType lang, gchar *scope) { switch (lang) { case TM_PARSER_PHP: case TM_PARSER_ZEPHIR: /* PHP parser uses two different scope separators but this would * complicate things in Geany so make sure there's just one type */ return replace_string_if_present(scope, "\\", "::"); case TM_PARSER_TCL: case TM_PARSER_TCLOO: /* The TCL(OO) parser returns scope prefixed with :: which we don't * want. */ if (g_str_has_prefix(scope, "::")) return g_strdup(scope + 2); break; } return scope; } /* whether or not to enable ctags roles for the given language and kind */ gboolean tm_parser_enable_role(TMParserType lang, gchar kind) { switch (lang) { case TM_PARSER_GDSCRIPT: return kind == 'c' ? FALSE : TRUE; case TM_PARSER_GO: /* 'p' is used both for package definition tags and imported package * tags and we can't tell which is which just by kind. By disabling * roles for this kind, we only get package definition tags. */ return kind == 'p' ? FALSE : TRUE; } return TRUE; } /* whether or not to enable ctags kinds for the given language */ gboolean tm_parser_enable_kind(TMParserType lang, gchar kind) { TMParserMap *map; guint i; if (lang >= TM_PARSER_COUNT) /* Fatal error but tm_parser_verify_type_mappings() will provide * better message later */ return FALSE; map = &parser_map[lang]; for (i = 0; i < map->size; i++) { if (map->entries[i].kind == kind) return map->entries[i].type != tm_tag_undef_t; } return FALSE; } gchar *tm_parser_format_variable(TMParserType lang, const gchar *name, const gchar *type, const gchar *scope) { gchar *ret, *name_full; if (!type) return NULL; if (scope) name_full = g_strconcat(scope, tm_parser_scope_separator_printable(lang), name, NULL); else name_full = g_strdup(name); switch (lang) { case TM_PARSER_GO: ret = g_strconcat(name_full, " ", type, NULL); break; case TM_PARSER_PASCAL: case TM_PARSER_PYTHON: ret = g_strconcat(name_full, ": ", type, NULL); break; default: ret = g_strconcat(type, " ", name_full, NULL); break; } g_free(name_full); return ret; } gchar *tm_parser_format_function(TMParserType lang, const gchar *fname, const gchar *args, const gchar *retval, const gchar *scope) { GString *str; if (!args) /* not a function */ return NULL; str = g_string_new(NULL); if (scope) { g_string_append(str, scope); g_string_append(str, tm_parser_scope_separator_printable(lang)); } g_string_append(str, fname); g_string_append_c(str, ' '); g_string_append(str, args); if (retval) { const gchar *sep = NULL; switch (lang) { /* retval after function */ case TM_PARSER_PASCAL: sep = ": "; break; case TM_PARSER_GDSCRIPT: case TM_PARSER_PYTHON: sep = " -> "; break; case TM_PARSER_GO: sep = " "; break; default: break; } if (sep) { /* retval after function */ g_string_append(str, sep); g_string_append(str, retval); } else { /* retval before function */ g_string_prepend_c(str, ' '); g_string_prepend(str, retval); } } return g_string_free(str, FALSE); } const gchar *tm_parser_scope_separator(TMParserType lang) { switch (lang) { case TM_PARSER_C: /* for C++ .h headers or C structs */ case TM_PARSER_CPP: case TM_PARSER_CUDA: case TM_PARSER_PHP: case TM_PARSER_POWERSHELL: case TM_PARSER_RUST: case TM_PARSER_TCL: case TM_PARSER_TCLOO: case TM_PARSER_ZEPHIR: return "::"; case TM_PARSER_LATEX: case TM_PARSER_MARKDOWN: case TM_PARSER_TXT2TAGS: return "\"\""; /* these parsers don't report nested scopes but default "." for scope separator * might appear in the text so use something more improbable */ case TM_PARSER_ASCIIDOC: case TM_PARSER_CONF: case TM_PARSER_REST: return "\x3"; default: return "."; } } const gchar *tm_parser_scope_separator_printable(TMParserType lang) { switch (lang) { case TM_PARSER_ASCIIDOC: case TM_PARSER_CONF: case TM_PARSER_LATEX: case TM_PARSER_MARKDOWN: case TM_PARSER_REST: case TM_PARSER_TXT2TAGS: return " > "; default: return tm_parser_scope_separator(lang); } } gboolean tm_parser_has_full_scope(TMParserType lang) { switch (lang) { /* These parsers include full hierarchy in the tag scope, separated by tm_parser_scope_separator() */ case TM_PARSER_ACTIONSCRIPT: case TM_PARSER_C: case TM_PARSER_CPP: case TM_PARSER_CUDA: case TM_PARSER_CSHARP: case TM_PARSER_COBOL: case TM_PARSER_D: case TM_PARSER_GDSCRIPT: case TM_PARSER_GO: case TM_PARSER_JAVA: case TM_PARSER_JAVASCRIPT: case TM_PARSER_JSON: case TM_PARSER_LATEX: case TM_PARSER_LUA: case TM_PARSER_MARKDOWN: case TM_PARSER_PHP: case TM_PARSER_POWERSHELL: case TM_PARSER_PYTHON: case TM_PARSER_R: case TM_PARSER_RUBY: case TM_PARSER_RUST: case TM_PARSER_SQL: case TM_PARSER_TCL: case TM_PARSER_TCLOO: case TM_PARSER_TXT2TAGS: case TM_PARSER_TYPESCRIPT: case TM_PARSER_VALA: case TM_PARSER_VHDL: case TM_PARSER_VERILOG: case TM_PARSER_ZEPHIR: case TM_PARSER_AUTOIT: return TRUE; /* These make use of the scope, but don't include nested hierarchy * (either as a parser limitation or a language semantic) */ case TM_PARSER_ADA: case TM_PARSER_ASCIIDOC: case TM_PARSER_CLOJURE: case TM_PARSER_CONF: case TM_PARSER_ERLANG: case TM_PARSER_FORTRAN: case TM_PARSER_OBJC: case TM_PARSER_REST: /* Other parsers don't use scope at all (or should be somewhere above) */ default: return FALSE; } } gboolean tm_parser_langs_compatible(TMParserType lang, TMParserType other) { if (lang == TM_PARSER_NONE || other == TM_PARSER_NONE) return FALSE; if (lang == other) return TRUE; /* Accept CPP tags for C lang and vice versa */ else if (lang == TM_PARSER_C && other == TM_PARSER_CPP) return TRUE; else if (lang == TM_PARSER_CPP && other == TM_PARSER_C) return TRUE; return FALSE; } geany-2.0/src/tagmanager/tm_parsers.h0000644000175000017500000000261114514252267014634 00000000000000/* * Copyright (c) 2019, Jiri Techet * * This source code is released for free distribution under the terms of the * GNU General Public License version 2 or (at your option) any later version. * * Declares parsers used by ctags */ #ifndef TM_PARSERS_H #define TM_PARSERS_H /* This file is included by ctags by defining EXTERNAL_PARSER_LIST_FILE inside * ctags/Makefile.am */ /* Keep in sync with tm_parser.h */ #define EXTERNAL_PARSER_LIST \ CParser, \ CppParser, \ JavaParser, \ MakefileParser, \ PascalParser, \ PerlParser, \ PhpParser, \ PythonParser, \ TexParser, \ AsmParser, \ IniconfParser, \ SqlParser, \ DocBookParser, \ ErlangParser, \ CssParser, \ RubyParser, \ TclParser, \ ShParser, \ DParser, \ FortranParser, \ GDScriptParser, \ DiffParser, \ VhdlParser, \ LuaParser, \ JavaScriptParser, \ HaskellParser, \ CsharpParser, \ BasicParser,\ HaxeParser,\ RstParser, \ HtmlParser, \ AdaParser, \ CUDAParser, \ MatLabParser, \ ValaParser, \ FlexParser, \ NsisParser, \ MarkdownParser, \ Txt2tagsParser, \ AbcParser, \ VerilogParser, \ RParser, \ CobolParser, \ ObjcParser, \ AsciidocParser, \ AbaqusParser, \ RustParser, \ GoParser, \ JsonParser, \ ZephirParser, \ PowerShellParser, \ JuliaParser, \ BibtexParser, \ CPreProParser, \ TclOOParser, \ ClojureParser, \ LispParser, \ TypeScriptParser, \ DosBatchParser, \ AutoItParser #endif geany-2.0/src/tagmanager/tm_tag.h0000644000175000017500000001407114514252267013733 00000000000000/* * * Copyright (c) 2001-2002, Biswapesh Chattopadhyay * Copyright 2005 The Geany contributors * * This source code is released for free distribution under the terms of the * GNU General Public License. * */ #ifndef TM_TAG_H #define TM_TAG_H /* @file The TMTag structure and the associated functions are used to manipulate tags and arrays of tags. Normally, you should not create tags individually but through an external interface such as tm_source_file_parse(), which generates an array of tags for the given source file. Once the tag list is generated, you can do various operations such as: -# Extract relevant tags using tm_tags_extract() -# Sort an array of tags using tm_tags_sort() -# Deduplicate an array of tags using tm_tags_dedup(). An important thing to remember here is that the tags operations such as extraction, sorting and deduplication do not change the tag itself in any way, but rather, manipulate pointers to the tags structure. The tags themselves are owned by the TMSourceFile structure which created them during parsing. So, be careful, for example, while deduping the tags array of a source file directly, since this might lead to 'dangling' tags whose pointers have been removed from the array. If you need to deduplicate, create a copy of the tag pointer array using tm_tags_extract(). */ #include "tm_source_file.h" #include "tm_parser.h" #include G_BEGIN_DECLS /** Use the TM_TAG() macro to cast a pointer to (TMTag *) */ #define TM_TAG(tag) ((TMTag *) tag) /** Tag Attributes. Note that some attributes are available to file pseudotags only. Attributes are useful for specifying as arguments to the builtin sort and dedup functions, and during printing or writing to file, since these functions can operate on the given set of attributes only. Tag attributes are bitmasks and can be 'OR'-ed bitwise to represent any combination (line TMTagType). */ typedef enum { tm_tag_attr_none_t = 0, /**< Undefined */ tm_tag_attr_name_t = 1, /**< Tag Name */ tm_tag_attr_type_t = 2, /**< Tag Type */ tm_tag_attr_file_t = 4, /**< File in which tag exists */ tm_tag_attr_line_t = 8, /**< Line number of tag */ tm_tag_attr_pos_t = 16, /**< Byte position of tag in the file (Obsolete) */ tm_tag_attr_scope_t = 32, /**< Scope of the tag */ tm_tag_attr_inheritance_t = 64, /**< Parent classes */ tm_tag_attr_arglist_t = 128, /**< Argument list */ tm_tag_attr_local_t = 256, /**< If it has local scope */ tm_tag_attr_time_t = 512, /**< Modification time (File tag only) */ tm_tag_attr_vartype_t = 1024, /**< Variable Type */ tm_tag_attr_access_t = 2048, /**< Access type (public/protected/private) */ tm_tag_attr_impl_t = 4096, /**< Implementation (e.g. virtual) */ tm_tag_attr_lang_t = 8192, /**< Language (File tag only) */ tm_tag_attr_inactive_t = 16384, /**< Inactive file (File tag only, obsolete) */ tm_tag_attr_flags_t = 32768, /**< Additional flags */ tm_tag_attr_max_t = 65535 /**< Maximum value */ } TMTagAttrType; /** Tag access type for C++/Java member functions and variables */ #define TAG_ACCESS_PUBLIC 'p' /**< Public member */ #define TAG_ACCESS_PROTECTED 'r' /**< Protected member */ #define TAG_ACCESS_PRIVATE 'v' /**< Private member */ #define TAG_ACCESS_FRIEND 'f' /**< Friend members/functions */ #define TAG_ACCESS_DEFAULT 'd' /**< Default access (Java) */ #define TAG_ACCESS_UNKNOWN 'x' /**< Unknown access type */ /** Tag implementation type for functions */ #define TAG_IMPL_VIRTUAL 'v' /**< Virtual implementation */ #define TAG_IMPL_UNKNOWN 'x' /**< Unknown implementation */ enum { tm_tag_flag_none_t = 0, /**< No flags */ tm_tag_flag_anon_t = 1, /**< Anonymous tag */ tm_tag_flag_max_t = 1, /**< Maximum value */ }; /** * The TMTag structure represents a single tag in the tag manager. **/ typedef struct TMTag { char *name; /**< Name of tag */ TMTagType type; /**< Tag Type */ gint refcount; /* the reference count of the tag */ /** These are tag attributes */ TMSourceFile *file; /**< File in which the tag occurs; NULL for global tags */ gulong line; /**< Line number of the tag */ gboolean local; /**< Is the tag of local scope */ guint flags; /**< Additional flags */ char *arglist; /**< Argument list (functions/prototypes/macros) */ char *scope; /**< Scope of tag */ char *inheritance; /**< Parent classes */ char *var_type; /**< Variable type (maps to struct for typedefs) */ char access; /**< Access type (public/protected/private/etc.) */ char impl; /**< Implementation (e.g. virtual) */ TMParserType lang; /* Programming language of the file */ gchar kind_letter; /* Kind letter from ctags */ } TMTag; /* The GType for a TMTag */ #define TM_TYPE_TAG (tm_tag_get_type()) GType tm_tag_get_type(void) G_GNUC_CONST; #ifdef GEANY_PRIVATE TMTag *tm_tag_new(void); void tm_tags_remove_file_tags(TMSourceFile *source_file, GPtrArray *tags_array); GPtrArray *tm_tags_merge(GPtrArray *big_array, GPtrArray *small_array, TMTagAttrType *sort_attributes, gboolean unref_duplicates); void tm_tags_sort(GPtrArray *tags_array, TMTagAttrType *sort_attributes, gboolean dedup, gboolean unref_duplicates); GPtrArray *tm_tags_extract(GPtrArray *tags_array, guint tag_types); void tm_tags_prune(GPtrArray *tags_array); void tm_tags_dedup(GPtrArray *tags_array, TMTagAttrType *sort_attributes, gboolean unref_duplicates); TMTag **tm_tags_find(const GPtrArray *tags_array, const char *name, gboolean partial, guint * tagCount); void tm_tags_array_free(GPtrArray *tags_array, gboolean free_all); const TMTag *tm_get_current_tag(GPtrArray *file_tags, const gulong line, const TMTagType tag_types); void tm_tag_unref(TMTag *tag); TMTag *tm_tag_ref(TMTag *tag); gboolean tm_tags_equal(const TMTag *a, const TMTag *b); gboolean tm_tag_is_anon(const TMTag *tag); #ifdef TM_DEBUG /* various debugging functions */ const char *tm_tag_type_name(const TMTag *tag); TMTagType tm_tag_name_type(const char* tag_name, TMParserType lang); void tm_tag_print(TMTag *tag, FILE *fp); void tm_tags_array_print(GPtrArray *tags, FILE *fp); gint tm_tag_scope_depth(const TMTag *t); #endif /* TM_DEBUG */ #endif /* GEANY_PRIVATE */ G_END_DECLS #endif /* TM_TAG_H */ geany-2.0/src/tagmanager/Makefile.in0000644000175000017500000006011114514252335014344 00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @USE_BUNDLED_REGEX_TRUE@am__append_1 = -I$(top_srcdir)/ctags/gnu_regex subdir = src/tagmanager ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx_17.m4 \ $(top_srcdir)/m4/geany-binreloc.m4 \ $(top_srcdir)/m4/geany-docutils.m4 \ $(top_srcdir)/m4/geany-doxygen.m4 \ $(top_srcdir)/m4/geany-gtk.m4 \ $(top_srcdir)/m4/geany-gtkdoc-header.m4 \ $(top_srcdir)/m4/geany-lib.m4 \ $(top_srcdir)/m4/geany-mac-integration.m4 \ $(top_srcdir)/m4/geany-mingw.m4 \ $(top_srcdir)/m4/geany-plugins.m4 \ $(top_srcdir)/m4/geany-prog-cxx.m4 \ $(top_srcdir)/m4/geany-revision.m4 \ $(top_srcdir)/m4/geany-socket.m4 \ $(top_srcdir)/m4/geany-status.m4 \ $(top_srcdir)/m4/geany-the-force.m4 \ $(top_srcdir)/m4/geany-utils.m4 $(top_srcdir)/m4/geany-vte.m4 \ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/iconv.m4 \ $(top_srcdir)/m4/intlmacosx.m4 $(top_srcdir)/m4/lib-ld.m4 \ $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \ $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(tagmanager_include_HEADERS) \ $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) am__DEPENDENCIES_1 = libtagmanager_la_DEPENDENCIES = $(top_builddir)/ctags/libctags.la \ $(am__DEPENDENCIES_1) am_libtagmanager_la_OBJECTS = tm_ctags.lo tm_parser.lo \ tm_source_file.lo tm_tag.lo tm_workspace.lo libtagmanager_la_OBJECTS = $(am_libtagmanager_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/tm_ctags.Plo \ ./$(DEPDIR)/tm_parser.Plo ./$(DEPDIR)/tm_source_file.Plo \ ./$(DEPDIR)/tm_tag.Plo ./$(DEPDIR)/tm_workspace.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libtagmanager_la_SOURCES) DIST_SOURCES = $(libtagmanager_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(tagmanager_includedir)" HEADERS = $(tagmanager_include_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) pkgdatadir = @pkgdatadir@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DEPENDENCIES = @DEPENDENCIES@ DLLTOOL = @DLLTOOL@ DOXYGEN = @DOXYGEN@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GEANY_DATA_DIR = @GEANY_DATA_DIR@ GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ GMSGFMT = @GMSGFMT@ GMSGFMT_015 = @GMSGFMT_015@ GREP = @GREP@ GTK_CFLAGS = @GTK_CFLAGS@ GTK_LIBS = @GTK_LIBS@ GTK_VERSION = @GTK_VERSION@ HAVE_CXX17 = @HAVE_CXX17@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTLLIBS = @INTLLIBS@ INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBGEANY_CFLAGS = @LIBGEANY_CFLAGS@ LIBGEANY_EXPORT_CFLAGS = @LIBGEANY_EXPORT_CFLAGS@ LIBGEANY_LDFLAGS = @LIBGEANY_LDFLAGS@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBICONV = @LTLIBICONV@ LTLIBINTL = @LTLIBINTL@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAC_INTEGRATION_CFLAGS = @MAC_INTEGRATION_CFLAGS@ MAC_INTEGRATION_LIBS = @MAC_INTEGRATION_LIBS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POSUB = @POSUB@ PYTHON = @PYTHON@ PYTHON_COMMAND = @PYTHON_COMMAND@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RST2HTML = @RST2HTML@ RST2PDF = @RST2PDF@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SORT = @SORT@ STRIP = @STRIP@ UNIQ = @UNIQ@ USE_NLS = @USE_NLS@ VERSION = @VERSION@ XGETTEXT = @XGETTEXT@ XGETTEXT_015 = @XGETTEXT_015@ XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AM_CPPFLAGS = -I$(srcdir) -I$(top_srcdir)/ctags/main \ -I$(top_srcdir)/ctags/libreadtags -I$(top_srcdir)/ctags/dsl \ -DGEANY_PRIVATE -DG_LOG_DOMAIN=\"Tagmanager\" $(am__append_1) AM_CFLAGS = \ $(GTK_CFLAGS) \ @LIBGEANY_CFLAGS@ noinst_LTLIBRARIES = libtagmanager.la tagmanager_includedir = $(includedir)/geany/tagmanager tagmanager_include_HEADERS = \ tm_source_file.h \ tm_tag.h \ tm_workspace.h \ tm_parser.h libtagmanager_la_SOURCES = \ tm_ctags.h \ tm_ctags.c \ tm_parser.h \ tm_parser.c \ tm_parsers.h \ tm_source_file.h \ tm_source_file.c \ tm_tag.h \ tm_tag.c \ tm_workspace.h \ tm_workspace.c libtagmanager_la_LIBADD = $(top_builddir)/ctags/libctags.la $(GTK_LIBS) all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/tagmanager/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu src/tagmanager/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libtagmanager.la: $(libtagmanager_la_OBJECTS) $(libtagmanager_la_DEPENDENCIES) $(EXTRA_libtagmanager_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libtagmanager_la_OBJECTS) $(libtagmanager_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tm_ctags.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tm_parser.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tm_source_file.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tm_tag.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tm_workspace.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-tagmanager_includeHEADERS: $(tagmanager_include_HEADERS) @$(NORMAL_INSTALL) @list='$(tagmanager_include_HEADERS)'; test -n "$(tagmanager_includedir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(tagmanager_includedir)'"; \ $(MKDIR_P) "$(DESTDIR)$(tagmanager_includedir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(tagmanager_includedir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(tagmanager_includedir)" || exit $$?; \ done uninstall-tagmanager_includeHEADERS: @$(NORMAL_UNINSTALL) @list='$(tagmanager_include_HEADERS)'; test -n "$(tagmanager_includedir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(tagmanager_includedir)'; $(am__uninstall_files_from_dir) ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(tagmanager_includedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/tm_ctags.Plo -rm -f ./$(DEPDIR)/tm_parser.Plo -rm -f ./$(DEPDIR)/tm_source_file.Plo -rm -f ./$(DEPDIR)/tm_tag.Plo -rm -f ./$(DEPDIR)/tm_workspace.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-tagmanager_includeHEADERS install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/tm_ctags.Plo -rm -f ./$(DEPDIR)/tm_parser.Plo -rm -f ./$(DEPDIR)/tm_source_file.Plo -rm -f ./$(DEPDIR)/tm_tag.Plo -rm -f ./$(DEPDIR)/tm_workspace.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-tagmanager_includeHEADERS .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ install-tagmanager_includeHEADERS installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-tagmanager_includeHEADERS .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: geany-2.0/src/tagmanager/tm_source_file.h0000644000175000017500000000364614514252267015465 00000000000000/* * * Copyright (c) 2001-2002, Biswapesh Chattopadhyay * Copyright 2005 The Geany contributors * * This source code is released for free distribution under the terms of the * GNU General Public License. * */ #ifndef TM_SOURCE_FILE_H #define TM_SOURCE_FILE_H #include #include #include #include "tm_parser.h" G_BEGIN_DECLS /* Casts a pointer to a pointer to a TMSourceFile structure */ #define TM_SOURCE_FILE(source_file) ((TMSourceFile *) source_file) /* Evaluates to X is X is defined, else evaluates to Y */ #define FALLBACK(X,Y) (X)?(X):(Y) /** * The TMSourceFile structure represents the source file and its tags in the tag manager. **/ typedef struct TMSourceFile { TMParserType lang; /* Programming language used */ char *file_name; /**< Full file name (inc. path) */ char *short_name; /**< Just the name of the file (without the path) */ GPtrArray *tags_array; /**< Sorted tag array obtained by parsing the object. @elementtype{TMTag} */ gboolean trust_file_scope; } TMSourceFile; GType tm_source_file_get_type(void); TMSourceFile *tm_source_file_new(const char *file_name, const char *name); void tm_source_file_free(TMSourceFile *source_file); gchar *tm_get_real_path(const gchar *file_name) #ifndef GEANY_PRIVATE G_DEPRECATED_FOR(utils_get_real_path) #endif ; #ifdef GEANY_PRIVATE const gchar *tm_source_file_get_lang_name(TMParserType lang); TMParserType tm_source_file_get_named_lang(const gchar *name); gboolean tm_source_file_parse(TMSourceFile *source_file, guchar* text_buf, gsize buf_size, gboolean use_buffer); GPtrArray *tm_source_file_read_tags_file(const gchar *tags_file, TMParserType mode); gboolean tm_source_file_write_tags_file(const gchar *tags_file, GPtrArray *tags_array); gchar tm_source_file_get_tag_impl(const gchar *impl); gchar tm_source_file_get_tag_access(const gchar *access); #endif /* GEANY_PRIVATE */ G_END_DECLS #endif /* TM_SOURCE_FILE_H */ geany-2.0/src/tagmanager/tm_workspace.c0000644000175000017500000011713614514252267015157 00000000000000/* * * Copyright (c) 2001-2002, Biswapesh Chattopadhyay * Copyright 2005 The Geany contributors * * This source code is released for free distribution under the terms of the * GNU General Public License. * */ /** * @file tm_workspace.h The TMWorkspace structure is meant to be used as a singleton to store application wide tag information. The workspace is intended to contain a list of global tags and a set of individual source files. */ #include #include #include #include #include #include #include #include #include "tm_workspace.h" #include "tm_ctags.h" #include "tm_tag.h" #include "tm_parser.h" /* when changing, always keep the three sort criteria below in sync */ static TMTagAttrType workspace_tags_sort_attrs[] = { tm_tag_attr_name_t, tm_tag_attr_file_t, tm_tag_attr_line_t, tm_tag_attr_type_t, tm_tag_attr_scope_t, tm_tag_attr_arglist_t, 0 }; /* for file tags the file is always identical, don't use for sorting */ static TMTagAttrType file_tags_sort_attrs[] = { tm_tag_attr_name_t, tm_tag_attr_line_t, tm_tag_attr_type_t, tm_tag_attr_scope_t, tm_tag_attr_arglist_t, 0 }; /* global tags don't have file/line information */ static TMTagAttrType global_tags_sort_attrs[] = { tm_tag_attr_name_t, tm_tag_attr_type_t, tm_tag_attr_scope_t, tm_tag_attr_arglist_t, 0 }; static TMTagType TM_TYPE_WITH_MEMBERS = tm_tag_class_t | tm_tag_struct_t | tm_tag_union_t | tm_tag_enum_t | tm_tag_interface_t; static TMTagType TM_GLOBAL_TYPE_MASK = tm_tag_class_t | tm_tag_enum_t | tm_tag_interface_t | tm_tag_struct_t | tm_tag_typedef_t | tm_tag_union_t | tm_tag_namespace_t; static TMWorkspace *theWorkspace = NULL; static void free_ptr_array(gpointer arr) { g_ptr_array_free(arr, TRUE); } static gboolean tm_create_workspace(void) { theWorkspace = g_new(TMWorkspace, 1); theWorkspace->tags_array = g_ptr_array_new(); theWorkspace->global_tags = g_ptr_array_new(); theWorkspace->source_files = g_ptr_array_new(); theWorkspace->typename_array = g_ptr_array_new(); theWorkspace->global_typename_array = g_ptr_array_new(); theWorkspace->source_file_map = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, free_ptr_array); tm_ctags_init(); tm_parser_verify_type_mappings(); return TRUE; } /* Frees the workspace structure and all child source files. Use only when exiting from the main program. */ void tm_workspace_free(void) { guint i; #ifdef TM_DEBUG g_message("Workspace destroyed"); #endif g_hash_table_destroy(theWorkspace->source_file_map); for (i=0; i < theWorkspace->source_files->len; ++i) tm_source_file_free(theWorkspace->source_files->pdata[i]); g_ptr_array_free(theWorkspace->source_files, TRUE); tm_tags_array_free(theWorkspace->global_tags, TRUE); g_ptr_array_free(theWorkspace->tags_array, TRUE); g_ptr_array_free(theWorkspace->typename_array, TRUE); g_ptr_array_free(theWorkspace->global_typename_array, TRUE); g_free(theWorkspace); theWorkspace = NULL; } /* Since TMWorkspace is a singleton, you should not create multiple workspaces, but get a pointer to the workspace whenever required. The first time a pointer is requested, or a source file is added to the workspace, a workspace is created. Subsequent calls to the function will return the created workspace. */ const TMWorkspace *tm_get_workspace(void) { if (NULL == theWorkspace) tm_create_workspace(); return theWorkspace; } static void tm_workspace_merge_tags(GPtrArray **big_array, GPtrArray *small_array) { GPtrArray *new_tags = tm_tags_merge(*big_array, small_array, workspace_tags_sort_attrs, FALSE); /* tags owned by TMSourceFile - free just the pointer array */ g_ptr_array_free(*big_array, TRUE); *big_array = new_tags; } static void merge_extracted_tags(GPtrArray **dest, GPtrArray *src, TMTagType tag_types) { GPtrArray *arr; arr = tm_tags_extract(src, tag_types); tm_workspace_merge_tags(dest, arr); g_ptr_array_free(arr, TRUE); } static void update_source_file(TMSourceFile *source_file, guchar* text_buf, gsize buf_size, gboolean use_buffer, gboolean update_workspace) { #ifdef TM_DEBUG g_message("Source file updating based on source file %s", source_file->file_name); #endif if (update_workspace) { /* tm_source_file_parse() deletes the tag objects - remove the tags from * workspace while they exist and can be scanned */ tm_tags_remove_file_tags(source_file, theWorkspace->tags_array); tm_tags_remove_file_tags(source_file, theWorkspace->typename_array); } tm_source_file_parse(source_file, text_buf, buf_size, use_buffer); tm_tags_sort(source_file->tags_array, file_tags_sort_attrs, FALSE, TRUE); if (update_workspace) { #ifdef TM_DEBUG g_message("Updating workspace from source file"); #endif tm_workspace_merge_tags(&theWorkspace->tags_array, source_file->tags_array); merge_extracted_tags(&(theWorkspace->typename_array), source_file->tags_array, TM_GLOBAL_TYPE_MASK); } #ifdef TM_DEBUG else g_message("Skipping workspace update because update_workspace is %s", update_workspace?"TRUE":"FALSE"); #endif } void tm_workspace_add_source_file_noupdate(TMSourceFile *source_file) { GPtrArray *file_arr; g_return_if_fail(source_file != NULL); g_ptr_array_add(theWorkspace->source_files, source_file); file_arr = g_hash_table_lookup(theWorkspace->source_file_map, source_file->short_name); if (!file_arr) { file_arr = g_ptr_array_new(); g_hash_table_insert(theWorkspace->source_file_map, g_strdup(source_file->short_name), file_arr); } g_ptr_array_add(file_arr, source_file); } /** Adds a source file to the workspace, parses it and updates the workspace tags. @param source_file The source file to add to the workspace. */ GEANY_API_SYMBOL void tm_workspace_add_source_file(TMSourceFile *source_file) { g_return_if_fail(source_file != NULL); tm_workspace_add_source_file_noupdate(source_file); update_source_file(source_file, NULL, 0, FALSE, TRUE); } /* Updates the source file by reparsing the text-buffer passed as parameter. Ctags will use a parsing based on buffer instead of on files. You should call this function when you don't want a previous saving of the file you're editing. It's useful for a "real-time" updating of the tags. The tags array and the tags themselves are destroyed and re-created, hence any other tag arrays pointing to these tags should be rebuilt as well. All sorting information is also lost. @param source_file The source file to update with a buffer. @param text_buf A text buffer. The user should take care of allocate and free it after the use here. @param buf_size The size of text_buf. */ void tm_workspace_update_source_file_buffer(TMSourceFile *source_file, guchar* text_buf, gsize buf_size) { update_source_file(source_file, text_buf, buf_size, TRUE, TRUE); } static void remove_source_file_map(TMSourceFile *source_file) { GPtrArray *file_arr = g_hash_table_lookup(theWorkspace->source_file_map, source_file->short_name); if (file_arr) g_ptr_array_remove_fast(file_arr, source_file); } /** Removes a source file from the workspace if it exists. This function also removes the tags belonging to this file from the workspace. To completely free the TMSourceFile pointer call tm_source_file_free() on it. @param source_file Pointer to the source file to be removed. */ GEANY_API_SYMBOL void tm_workspace_remove_source_file(TMSourceFile *source_file) { guint i; g_return_if_fail(source_file != NULL); for (i=0; i < theWorkspace->source_files->len; ++i) { if (theWorkspace->source_files->pdata[i] == source_file) { tm_tags_remove_file_tags(source_file, theWorkspace->tags_array); tm_tags_remove_file_tags(source_file, theWorkspace->typename_array); remove_source_file_map(source_file); g_ptr_array_remove_index_fast(theWorkspace->source_files, i); return; } } } /* Recreates workspace tag array from all member TMSourceFile objects. Use if you want to globally refresh the workspace. This function does not call tm_source_file_update() which should be called before this function on source files which need to be reparsed. */ static void tm_workspace_update(void) { guint i, j; TMSourceFile *source_file; #ifdef TM_DEBUG g_message("Recreating workspace tags array"); #endif g_ptr_array_set_size(theWorkspace->tags_array, 0); #ifdef TM_DEBUG g_message("Total %d objects", theWorkspace->source_files->len); #endif for (i=0; i < theWorkspace->source_files->len; ++i) { source_file = theWorkspace->source_files->pdata[i]; #ifdef TM_DEBUG g_message("Adding tags of %s", source_file->file_name); #endif if (source_file->tags_array->len > 0) { for (j = 0; j < source_file->tags_array->len; ++j) { g_ptr_array_add(theWorkspace->tags_array, source_file->tags_array->pdata[j]); } } } #ifdef TM_DEBUG g_message("Total: %d tags", theWorkspace->tags_array->len); #endif tm_tags_sort(theWorkspace->tags_array, workspace_tags_sort_attrs, TRUE, FALSE); g_ptr_array_free(theWorkspace->typename_array, TRUE); theWorkspace->typename_array = tm_tags_extract(theWorkspace->tags_array, TM_GLOBAL_TYPE_MASK); } /** Adds multiple source files to the workspace and updates the workspace tag arrays. This is more efficient than calling tm_workspace_add_source_file() and tm_workspace_update_source_file() separately for each of the files. @param source_files @elementtype{TMSourceFile} The source files to be added to the workspace. */ GEANY_API_SYMBOL void tm_workspace_add_source_files(GPtrArray *source_files) { guint i; g_return_if_fail(source_files != NULL); for (i = 0; i < source_files->len; i++) { TMSourceFile *source_file = source_files->pdata[i]; tm_workspace_add_source_file_noupdate(source_file); update_source_file(source_file, NULL, 0, FALSE, FALSE); } tm_workspace_update(); } /** Removes multiple source files from the workspace and updates the workspace tag arrays. This is more efficient than calling tm_workspace_remove_source_file() separately for each of the files. To completely free the TMSourceFile pointers call tm_source_file_free() on each of them. @param source_files @elementtype{TMSourceFile} The source files to be removed from the workspace. */ GEANY_API_SYMBOL void tm_workspace_remove_source_files(GPtrArray *source_files) { guint i, j; g_return_if_fail(source_files != NULL); //TODO: sort both arrays by pointer value and remove in single pass for (i = 0; i < source_files->len; i++) { TMSourceFile *source_file = source_files->pdata[i]; for (j = 0; j < theWorkspace->source_files->len; j++) { if (theWorkspace->source_files->pdata[j] == source_file) { remove_source_file_map(source_file); g_ptr_array_remove_index_fast(theWorkspace->source_files, j); break; } } } tm_workspace_update(); } /* Loads the global tag list from the specified file. The global tag list should have been first created using tm_workspace_create_global_tags(). @param tags_file The file containing global tags. @return TRUE on success, FALSE on failure. @see tm_workspace_create_global_tags() */ gboolean tm_workspace_load_global_tags(const char *tags_file, TMParserType mode) { GPtrArray *file_tags, *new_tags; file_tags = tm_source_file_read_tags_file(tags_file, mode); if (!file_tags) return FALSE; tm_tags_sort(file_tags, global_tags_sort_attrs, TRUE, TRUE); /* reorder the whole array, because tm_tags_find expects a sorted array */ new_tags = tm_tags_merge(theWorkspace->global_tags, file_tags, global_tags_sort_attrs, TRUE); g_ptr_array_free(theWorkspace->global_tags, TRUE); g_ptr_array_free(file_tags, TRUE); theWorkspace->global_tags = new_tags; g_ptr_array_free(theWorkspace->global_typename_array, TRUE); theWorkspace->global_typename_array = tm_tags_extract(new_tags, TM_GLOBAL_TYPE_MASK); return TRUE; } static gboolean write_includes_file(const gchar *outf, GList *includes_files) { FILE *fp = g_fopen(outf, "w"); GList *node = includes_files; if (!fp) return FALSE; while (node) { char *str = g_strdup_printf("#include \"%s\"\n", (char*)node->data); size_t str_len = strlen(str); fwrite(str, str_len, 1, fp); g_free(str); node = g_list_next(node); } return fclose(fp) == 0; } static gchar *create_temp_file(const gchar *tpl) { gchar *name; gint fd; fd = g_file_open_tmp(tpl, &name, NULL); if (fd < 0) name = NULL; else close(fd); return name; } static GList *lookup_sources(const gchar **sources, gint sources_count) { GList *source_files = NULL; GHashTable *table; /* used for deduping */ gint i; table = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, NULL); for (i = 0; i < sources_count; i++) { if (!g_hash_table_lookup(table, sources[i])) { gchar* file_name_copy = g_strdup(sources[i]); source_files = g_list_prepend(source_files, file_name_copy); g_hash_table_insert(table, file_name_copy, file_name_copy); } } g_hash_table_destroy(table); return g_list_reverse(source_files); } static gchar *pre_process_file(const gchar *cmd, const gchar *inf) { gint ret; gchar *outf = create_temp_file("tmp_XXXXXX.cpp"); gchar *tmp_errfile; gchar *errors = NULL; gchar *command; if (!outf) return NULL; tmp_errfile = create_temp_file("tmp_XXXXXX"); if (!tmp_errfile) { g_unlink(outf); g_free(outf); return NULL; } command = g_strdup_printf("%s %s >%s 2>%s", cmd, inf, outf, tmp_errfile); #ifdef TM_DEBUG g_message("Executing: %s", command); #endif ret = system(command); g_free(command); g_file_get_contents(tmp_errfile, &errors, NULL, NULL); if (errors && *errors) g_printerr("%s\n", errors); g_free(errors); g_unlink(tmp_errfile); g_free(tmp_errfile); if (ret == -1) { g_unlink(outf); g_free(outf); return NULL; } return outf; } static gboolean create_global_tags_preprocessed(const char *pre_process_cmd, GList *source_files, const char *tags_file, TMParserType lang) { TMSourceFile *source_file; gboolean ret = FALSE; gchar *temp_file2; gchar *temp_file = create_temp_file("tmp_XXXXXX.cpp"); GPtrArray *filtered_tags; #ifdef TM_DEBUG g_message ("writing out files to %s\n", temp_file); #endif if (!temp_file) return FALSE; if (!write_includes_file(temp_file, source_files)) goto cleanup; temp_file2 = pre_process_file(pre_process_cmd, temp_file); if (temp_file2) { g_unlink(temp_file); g_free(temp_file); temp_file = temp_file2; } else goto cleanup; source_file = tm_source_file_new(temp_file, tm_source_file_get_lang_name(lang)); if (!source_file) goto cleanup; update_source_file(source_file, NULL, 0, FALSE, FALSE); if (source_file->tags_array->len == 0) { tm_source_file_free(source_file); goto cleanup; } tm_tags_sort(source_file->tags_array, global_tags_sort_attrs, TRUE, FALSE); filtered_tags = tm_tags_extract(source_file->tags_array, ~(tm_tag_local_var_t | tm_tag_include_t)); ret = tm_source_file_write_tags_file(tags_file, filtered_tags); g_ptr_array_free(filtered_tags, TRUE); tm_source_file_free(source_file); cleanup: g_unlink(temp_file); g_free(temp_file); return ret; } static gboolean create_global_tags_direct(GList *source_files, const char *tags_file, TMParserType lang) { GList *node; GPtrArray *filtered_tags; GPtrArray *tags = g_ptr_array_new(); GSList *tm_source_files = NULL; gboolean ret = FALSE; for (node = source_files; node; node = node->next) { TMSourceFile *source_file = tm_source_file_new(node->data, tm_source_file_get_lang_name(lang)); if (source_file) { guint i; tm_source_files = g_slist_prepend(tm_source_files, source_file); tm_source_file_parse(source_file, NULL, 0, FALSE); for (i = 0; i < source_file->tags_array->len; i++) g_ptr_array_add(tags, source_file->tags_array->pdata[i]); } } filtered_tags = tm_tags_extract(tags, ~(tm_tag_local_var_t | tm_tag_include_t)); tm_tags_sort(filtered_tags, global_tags_sort_attrs, TRUE, FALSE); if (filtered_tags->len > 0) ret = tm_source_file_write_tags_file(tags_file, filtered_tags); g_ptr_array_free(tags, TRUE); g_ptr_array_free(filtered_tags, TRUE); g_slist_free_full(tm_source_files, (GDestroyNotify)tm_source_file_free); return ret; } /* Creates a list of global tags. Ideally, this should be created once during installations so that all users can use the same file. This is because a full scale global tag list can occupy several megabytes of disk space. @param pre_process_cmd The pre-processing command. This is executed via system(), so you can pass stuff like 'gcc -E -dD -P `gnome-config --cflags gnome`'. @param sources Source files to process. Wildcards such as '/usr/include/a*.h' are allowed. @param tags_file The file where the tags will be stored. @param lang The language to use for the tags file. @return TRUE on success, FALSE on failure. */ gboolean tm_workspace_create_global_tags(const char *pre_process_cmd, const char **sources, int sources_count, const char *tags_file, TMParserType lang) { gboolean ret = FALSE; GList *source_files = lookup_sources(sources, sources_count); if (pre_process_cmd) ret = create_global_tags_preprocessed(pre_process_cmd, source_files, tags_file, lang); else ret = create_global_tags_direct(source_files, tags_file, lang); g_list_free_full(source_files, g_free); return ret; } static void fill_find_tags_array(GPtrArray *dst, const GPtrArray *src, const char *name, const char *scope, TMTagType type, TMParserType lang) { TMTag **tag; guint i, num; if (!src || !dst || !name || !*name) return; tag = tm_tags_find(src, name, FALSE, &num); for (i = 0; i < num; ++i) { if ((type & (*tag)->type) && tm_parser_langs_compatible(lang, (*tag)->lang) && (!scope || g_strcmp0((*tag)->scope, scope) == 0)) { g_ptr_array_add(dst, *tag); } tag++; } } /* Returns all matching tags found in the workspace. @param name The name of the tag to find. @param scope The scope name of the tag to find, or NULL. @param type The tag types to return (TMTagType). Can be a bitmask. @param attrs The attributes to sort and dedup on (0 terminated integer array). @param lang Specifies the language(see the table in tm_parsers.h) of the tags to be found, -1 for all @return Array of matching tags. */ GPtrArray *tm_workspace_find(const char *name, const char *scope, TMTagType type, TMTagAttrType *attrs, TMParserType lang) { GPtrArray *tags = g_ptr_array_new(); fill_find_tags_array(tags, theWorkspace->tags_array, name, scope, type, lang); fill_find_tags_array(tags, theWorkspace->global_tags, name, scope, type, lang); if (attrs) tm_tags_sort(tags, attrs, TRUE, FALSE); return tags; } gboolean tm_workspace_is_autocomplete_tag(TMTag *tag, TMSourceFile *current_file, guint current_line, const gchar *current_scope) { TMParserType lang = current_file ? current_file->lang : TM_PARSER_NONE; /* ignore local variables from other files/functions or after current line */ gboolean valid = !(tag->type & tm_tag_local_var_t) || (current_file == tag->file && current_line >= tag->line && g_strcmp0(current_scope, tag->scope) == 0); /* tag->local indicates per-file-only visibility such as static C functions */ gboolean valid_local = !tag->local || current_file == tag->file; return valid && valid_local && !tm_tag_is_anon(tag) && tm_parser_langs_compatible(lang, tag->lang) && !(tag->type & tm_tag_include_t); } #if ! GLIB_CHECK_VERSION(2, 54, 0) static gboolean g_ptr_array_find (GPtrArray *haystack, gconstpointer needle, guint *index_) { guint i; g_return_val_if_fail (haystack != NULL, FALSE); for (i = 0; i < haystack->len; i++) { if (g_direct_equal (g_ptr_array_index (haystack, i), needle)) { if (index_ != NULL) *index_ = i; return TRUE; } } return FALSE; } #endif typedef struct { TMSourceFile *file; GPtrArray *header_candidates; GHashTable *includes; guint line; const gchar *scope; } CopyInfo; static gboolean is_any_tag(TMTag *tag, CopyInfo *info) { return TRUE; } static gboolean is_local_tag(TMTag *tag, CopyInfo *info) { return tag->type & tm_tag_local_var_t; } static gboolean is_non_local_tag(TMTag *tag, CopyInfo *info) { return !is_local_tag(tag, info); } /* non-local tag not from current file, header, or included files */ static gboolean is_workspace_tag(TMTag *tag, CopyInfo *info) { return tag->file != info->file && (!info->header_candidates || !g_ptr_array_find(info->header_candidates, tag->file, NULL)) && !g_hash_table_lookup(info->includes, tag->file) && is_non_local_tag(tag, info); } static void copy_tags(GPtrArray *dst, TMTag **src, guint src_len, GHashTable *name_table, gint num, gboolean (*predicate) (TMTag *, CopyInfo *), CopyInfo *info) { guint i; g_return_if_fail(src && dst); for (i = 0; i < src_len && num > 0; i++) { TMTag *tag = *src; if (predicate(tag, info) && tm_workspace_is_autocomplete_tag(tag, info->file, info->line, info->scope) && !g_hash_table_contains(name_table, tag->name)) { g_ptr_array_add(dst, tag); g_hash_table_add(name_table, tag->name); num--; } src++; } } static void fill_find_tags_array_prefix(GPtrArray *dst, const char *name, CopyInfo *info, guint max_num) { TMTag **found; guint count; GHashTable *name_table; if (!dst || !name || !*name) return; name_table = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, NULL); if (info->file) { found = tm_tags_find(info->file->tags_array, name, TRUE, &count); if (found) { copy_tags(dst, found, count, name_table, max_num - dst->len, is_local_tag, info); if (dst->len < max_num) copy_tags(dst, found, count, name_table, max_num - dst->len, is_non_local_tag, info); } } if (dst->len < max_num && info->header_candidates) { guint i; for (i = 0; i < info->header_candidates->len; i++) { TMSourceFile *hdr = info->header_candidates->pdata[i]; found = tm_tags_find(hdr->tags_array, name, TRUE, &count); if (found) copy_tags(dst, found, count, name_table, max_num - dst->len, is_non_local_tag, info); } } if (dst->len < max_num) { GHashTableIter iter; gpointer key; g_hash_table_iter_init(&iter, info->includes); while (g_hash_table_iter_next(&iter, &key, NULL)) { TMSourceFile *include_file = key; found = tm_tags_find(include_file->tags_array, name, TRUE, &count); if (found) copy_tags(dst, found, count, name_table, max_num - dst->len, is_non_local_tag, info); } } if (dst->len < max_num) { found = tm_tags_find(theWorkspace->tags_array, name, TRUE, &count); if (found) copy_tags(dst, found, count, name_table, max_num - dst->len, is_workspace_tag, info); } if (dst->len < max_num) { found = tm_tags_find(theWorkspace->global_tags, name, TRUE, &count); if (found) copy_tags(dst, found, count, name_table, max_num - dst->len, is_any_tag, info); } g_hash_table_unref(name_table); } /* return TMSourceFile files corresponding to files included in 'source'; * in addition, fill header_candidates with TMSourceFiles that could be the header * of 'source' based on the file name */ static GHashTable *get_includes(TMSourceFile *source, GPtrArray **header_candidates) { GHashTable *includes = g_hash_table_new(NULL, NULL); GPtrArray *headers; gchar *src_basename, *ptr; guint i; *header_candidates = NULL; if (!source || (source->lang != TM_PARSER_C && source->lang != TM_PARSER_CPP)) return includes; src_basename = g_strdup(source->short_name); if ((ptr = strrchr(src_basename, '.')) != NULL) *ptr = '\0'; headers = tm_tags_extract(source->tags_array, tm_tag_include_t); for (i = 0; i < headers->len; i++) { TMTag *hdr_tag = headers->pdata[i]; gchar *hdr_name = g_path_get_basename(hdr_tag->name); GPtrArray *tm_files = g_hash_table_lookup(theWorkspace->source_file_map, hdr_name); if (tm_files && tm_files->len > 0) { guint j; if (!*header_candidates) { gchar *hdr_basename = g_strdup(hdr_name); if ((ptr = strrchr(hdr_basename, '.')) != NULL) *ptr = '\0'; if (g_strcmp0(hdr_basename, src_basename) == 0) *header_candidates = tm_files; g_free(hdr_basename); } for (j = 0; j < tm_files->len; j++) g_hash_table_add(includes, tm_files->pdata[j]); } g_free(hdr_name); } g_ptr_array_free(headers, TRUE); g_free(src_basename); return includes; } typedef struct { TMSourceFile *file; GPtrArray *header_candidates; GHashTable *includes; gboolean sort_by_name; } SortInfo; static gint sort_found_tags(gconstpointer a, gconstpointer b, gpointer user_data) { SortInfo *info = user_data; const TMTag *t1 = *((TMTag **) a); const TMTag *t2 = *((TMTag **) b); /* sort local vars first (with highest line number first), * followed by tags from current file, * followed by tags from header, * followed by tags from other included files, * followed by workspace tags, * followed by global tags */ if (t1->type & tm_tag_local_var_t && t2->type & tm_tag_local_var_t) return info->sort_by_name ? g_strcmp0(t1->name, t2->name) : t2->line - t1->line; else if (t1->type & tm_tag_local_var_t) return -1; else if (t2->type & tm_tag_local_var_t) return 1; else if (t1->file == info->file && t2->file != info->file) return -1; else if (t2->file == info->file && t1->file != info->file) return 1; else if (info->header_candidates && g_ptr_array_find(info->header_candidates, t1->file, NULL) && !g_ptr_array_find(info->header_candidates, t2->file, NULL)) return -1; else if (info->header_candidates && g_ptr_array_find(info->header_candidates, t2->file, NULL) && !g_ptr_array_find(info->header_candidates, t1->file, NULL)) return 1; else if (g_hash_table_lookup(info->includes, t1->file) && !g_hash_table_lookup(info->includes, t2->file)) return -1; else if (g_hash_table_lookup(info->includes, t2->file) && !g_hash_table_lookup(info->includes, t1->file)) return 1; else if (t1->file && !t2->file) return -1; else if (t2->file && !t1->file) return 1; return g_strcmp0(t1->name, t2->name); } /* Returns tags with the specified prefix sorted by name, ignoring local variables from other files/functions or after current line. If there are several tags with the same name, only one of them appears in the resulting array. @param prefix The prefix of the tag to find. @param lang Specifies the language(see the table in tm_parsers.h) of the tags to be found, -1 for all. @param max_num The maximum number of tags to return. @return Array of matching tags sorted by their name. */ GPtrArray *tm_workspace_find_prefix(const char *prefix, TMSourceFile *current_file, guint current_line, const gchar *current_scope, guint max_num) { GPtrArray *tags = g_ptr_array_new(); GPtrArray *header_candidates; SortInfo sort_info; CopyInfo copy_info; GHashTable *includes = get_includes(current_file, &header_candidates); copy_info.file = current_file; copy_info.header_candidates = header_candidates; copy_info.includes = includes; copy_info.line = current_line; copy_info.scope = current_scope; fill_find_tags_array_prefix(tags, prefix, ©_info, max_num); /* sort based on how "close" the tag is to current line with local * variables first */ sort_info.file = current_file; sort_info.header_candidates = header_candidates; sort_info.includes = includes; sort_info.sort_by_name = TRUE; g_ptr_array_sort_with_data(tags, sort_found_tags, &sort_info); g_hash_table_destroy(includes); return tags; } static gboolean replace_with_char(gchar *haystack, const gchar *needle, char replacement) { gchar *pos = strstr(haystack, needle); if (pos) { while (*needle) { *pos = replacement; needle++; pos++; } return TRUE; } return FALSE; } static gboolean replace_parens_with_char(gchar *haystack, gchar paren_begin, gchar paren_end, char replacement) { gchar needle[2] = {paren_begin, '\0'}; gchar *pos = strstr(haystack, needle); gint nesting = 0; if (pos) { while (*pos) { if (*pos == paren_begin) nesting++; else if (*pos == paren_end) nesting--; *pos = replacement; if (nesting == 0) break; pos++; } return TRUE; } return FALSE; } static gchar *strip_type(const gchar *scoped_name, TMParserType lang, gboolean remove_scope) { if (scoped_name != NULL) { const gchar *sep = tm_parser_scope_separator(lang); gchar *name = g_strdup(scoped_name); gchar *scope_suffix; /* remove pointers, parens and keywords appearing in types */ g_strdelimit(name, "*^&", ' '); while (replace_parens_with_char(name, '[', ']', ' ')) {} while (replace_parens_with_char(name, '<', '>', ' ')) {} while (replace_with_char(name, "const ", ' ')) {} while (replace_with_char(name, " const", ' ')) {} while (replace_with_char(name, " struct", ' ')) {} /* remove everything before final scope separator */ if (remove_scope && (scope_suffix = g_strrstr(name, sep))) { scope_suffix += strlen(sep); scope_suffix = g_strdup(scope_suffix); g_free(name); name = scope_suffix; } g_strstrip(name); return name; } return NULL; } /* Gets all members of type_tag; search them inside the all array. * The namespace parameter determines whether we are performing the "namespace" * search (user has typed something like "A::" where A is a type) or "scope" search * (user has typed "a." where a is a global struct-like variable). With the * namespace search we return all direct descendants of any type while with the * scope search we return only those which can be invoked on a variable (member, * method, etc.). */ static GPtrArray * find_scope_members_tags (const GPtrArray *all, TMTag *type_tag, gboolean namespace, guint depth) { TMTagType member_types = tm_tag_max_t & ~(TM_TYPE_WITH_MEMBERS | tm_tag_typedef_t); GPtrArray *tags; gchar *scope; guint i; if (depth == 10) return NULL; /* simple inheritence cycle avoidance */ tags = g_ptr_array_new(); if (namespace) member_types = tm_tag_max_t; if (type_tag->scope && *(type_tag->scope)) scope = g_strconcat(type_tag->scope, tm_parser_scope_separator(type_tag->lang), type_tag->name, NULL); else scope = g_strdup(type_tag->name); for (i = 0; i < all->len; ++i) { TMTag *tag = TM_TAG (all->pdata[i]); if (tag && (tag->type & member_types) && tag->scope && tag->scope[0] != '\0' && tm_parser_langs_compatible(tag->lang, type_tag->lang) && strcmp(scope, tag->scope) == 0 && (!namespace || !tm_tag_is_anon(tag))) { g_ptr_array_add (tags, tag); } } /* add members from parent classes */ if (!namespace && (type_tag->type & (tm_tag_class_t | tm_tag_struct_t)) && type_tag->inheritance && *type_tag->inheritance) { gchar *stripped = strip_type(type_tag->inheritance, type_tag->lang, FALSE); gchar **split_strv = g_strsplit(stripped, ",", -1); /* parent classes */ const gchar *parent; g_free(stripped); for (i = 0; (parent = split_strv[i]) != NULL; i++) { GPtrArray *parent_tags; stripped = strip_type(parent, type_tag->lang, TRUE); parent_tags = tm_workspace_find(stripped, NULL, tm_tag_class_t | tm_tag_struct_t, NULL, type_tag->lang); if (parent_tags->len > 0) { TMTag *parent_tag = parent_tags->pdata[0]; GPtrArray *parent_members = find_scope_members_tags( parent_tag->file ? parent_tag->file->tags_array : all, parent_tag, FALSE, depth + 1); if (parent_members) { guint j; for (j = 0; j < parent_members->len; j++) g_ptr_array_add (tags, parent_members->pdata[j]); g_ptr_array_free(parent_members, TRUE); } } g_ptr_array_free(parent_tags, TRUE); g_free(stripped); } g_strfreev(split_strv); } g_free(scope); if (tags->len == 0) { g_ptr_array_free(tags, TRUE); return NULL; } if (depth == 0) { TMTagAttrType sort_attrs[] = {tm_tag_attr_name_t, 0}; tm_tags_sort(tags, sort_attrs, TRUE, FALSE); } return tags; } /* Gets all members of the type with the given name; search them inside tags_array */ static GPtrArray * find_scope_members (const GPtrArray *tags_array, const gchar *name, TMSourceFile *file, TMParserType lang, gboolean namespace) { GPtrArray *res = NULL; gchar *type_name; guint i; g_return_val_if_fail(name && *name, NULL); type_name = g_strdup(name); /* Check if type_name is a type that can possibly contain members. * Try to resolve intermediate typedefs to get the real type name. Also * add scope information to the name if applicable. * The loop below loops only when resolving typedefs - avoid possibly infinite * loop when typedefs create a cycle by adding some limits. */ for (i = 0; i < 5; i++) { guint j; GPtrArray *type_tags; TMTagType types = TM_TYPE_WITH_MEMBERS | tm_tag_typedef_t; TMTag *tag = NULL; if (!namespace) types &= ~tm_tag_enum_t; type_tags = g_ptr_array_new(); fill_find_tags_array(type_tags, tags_array, type_name, NULL, types, lang); for (j = 0; j < type_tags->len; j++) { TMTag *test_tag = TM_TAG(type_tags->pdata[j]); /* anonymous type defined in a different file than the variable - * this isn't the type we are looking for */ if (tm_tag_is_anon(test_tag) && (file != test_tag->file || test_tag->file == NULL)) continue; tag = test_tag; /* prefer non-typedef tags because we can be sure they contain members */ if (test_tag->type != tm_tag_typedef_t) break; } g_ptr_array_free(type_tags, TRUE); if (!tag) /* not a type that can contain members */ break; /* intermediate typedef - resolve to the real type */ if (tag->type == tm_tag_typedef_t) { if (tag->var_type && tag->var_type[0] != '\0') { g_free(type_name); type_name = strip_type(tag->var_type, tag->lang, TRUE); file = tag->file; continue; } break; } else /* real type with members */ { /* use the same file as the composite type if file information available */ res = find_scope_members_tags(tag->file ? tag->file->tags_array : tags_array, tag, namespace, 0); break; } } g_free(type_name); return res; } /* Checks whether a member tag is directly accessible from method */ static gboolean member_accessible(const GPtrArray *tags, const gchar *method_scope, TMTag *member_tag, TMParserType lang) { const gchar *sep = tm_parser_scope_separator(lang); gboolean ret = FALSE; gchar **comps; guint len; /* method scope is in the form ...::class_name::method_name */ comps = g_strsplit (method_scope, sep, 0); len = g_strv_length(comps); if (len > 1) { gchar *cls = comps[len - 2]; if (*cls) { /* find method's class members */ GPtrArray *cls_tags = find_scope_members(tags, cls, NULL, lang, FALSE); if (cls_tags) { guint i; /* check if one of the class members is member_tag */ for (i = 0; i < cls_tags->len; i++) { TMTag *t = cls_tags->pdata[i]; if (t == member_tag) { ret = TRUE; break; } } g_ptr_array_free(cls_tags, TRUE); } } } g_strfreev(comps); return ret; } /* For an array of variable/type tags, find members inside the types */ static GPtrArray * find_scope_members_all(const GPtrArray *tags, const GPtrArray *searched_array, TMParserType lang, gboolean member, const gchar *current_scope) { GPtrArray *member_tags = NULL; guint i; /* there may be several variables/types with the same name - try each of them until * we find something */ for (i = 0; i < tags->len && !member_tags; i++) { TMTag *tag = TM_TAG(tags->pdata[i]); TMTagType member_types = tm_tag_member_t | tm_tag_field_t | tm_tag_method_t; TMTagType types = TM_TYPE_WITH_MEMBERS | tm_tag_typedef_t; if (tag->type & types) /* type: namespace search */ { if (tag->type & tm_tag_typedef_t) member_tags = find_scope_members(searched_array, tag->name, tag->file, lang, TRUE); else member_tags = find_scope_members_tags(tag->file ? tag->file->tags_array : searched_array, tag, TRUE, 0); } else if (tag->var_type) /* variable: scope search */ { /* The question now is whether we should use member tags (such as * tm_tag_field_t, tm_tag_member_t) or not. We want them if member==TRUE * (which means user has typed something like foo.bar.) or if we are * inside a method where foo is a class member, we want scope completion * for foo. */ if (!(tag->type & member_types) || member || member_accessible(searched_array, current_scope, tag, lang)) { gchar *tag_type = strip_type(tag->var_type, tag->lang, TRUE); member_tags = find_scope_members(searched_array, tag_type, tag->file, lang, FALSE); g_free(tag_type); } } } return member_tags; } static GPtrArray *find_namespace_members_all(const GPtrArray *tags, const GPtrArray *searched_array) { GPtrArray *member_tags = NULL; guint i; for (i = 0; i < tags->len && !member_tags; i++) { TMTag *tag = TM_TAG(tags->pdata[i]); member_tags = find_scope_members_tags(searched_array, tag, TRUE, 0); } return member_tags; } /* Returns all member tags of a struct/union/class if the provided name is a variable of such a type or the name of the type. @param source_file TMSourceFile of the edited source file @param name Name of the variable/type whose members are searched @param function TRUE if the name is a name of a function @param member TRUE if invoked on class/struct member (e.g. after the last dot in foo.bar.) @param current_scope The current scope in the editor @param current_line The current line in the editor @param search_namespace Whether to search the contents of namespace (e.g. after MyNamespace::) @return A GPtrArray of TMTag pointers to struct/union/class members or NULL when not found */ GPtrArray * tm_workspace_find_scope_members (TMSourceFile *source_file, const char *name, gboolean function, gboolean member, const gchar *current_scope, guint current_line, gboolean search_namespace) { TMParserType lang = source_file ? source_file->lang : TM_PARSER_NONE; GPtrArray *tags, *member_tags = NULL; TMTagType function_types = tm_tag_function_t | tm_tag_method_t | tm_tag_macro_with_arg_t | tm_tag_prototype_t; TMTagType tag_type = tm_tag_max_t & ~(function_types | tm_tag_enumerator_t | tm_tag_namespace_t | tm_tag_package_t); TMTagAttrType sort_attr[] = {tm_tag_attr_name_t, 0}; if (search_namespace) { tags = tm_workspace_find(name, NULL, tm_tag_namespace_t, NULL, lang); member_tags = find_namespace_members_all(tags, theWorkspace->tags_array); if (!member_tags) member_tags = find_namespace_members_all(tags, theWorkspace->global_tags); g_ptr_array_free(tags, TRUE); } if (!member_tags) { SortInfo info; guint i; if (function) tag_type = function_types; /* tags corresponding to the variable/type name */ tags = tm_workspace_find(name, NULL, tag_type, NULL, lang); /* remove invalid local tags and sort tags so "nearest" tags are first */ for (i = 0; i < tags->len; i++) { TMTag *tag = tags->pdata[i]; if (!tm_workspace_is_autocomplete_tag(tag, source_file, current_line, current_scope)) tags->pdata[i] = NULL; } tm_tags_prune(tags); info.file = source_file; info.sort_by_name = FALSE; info.includes = get_includes(source_file, &info.header_candidates); g_ptr_array_sort_with_data(tags, sort_found_tags, &info); /* Start searching inside the source file, continue with workspace tags and * end with global tags. This way we find the "closest" tag to the current * file in case there are more of them. */ if (source_file) member_tags = find_scope_members_all(tags, source_file->tags_array, lang, member, current_scope); if (!member_tags) member_tags = find_scope_members_all(tags, theWorkspace->tags_array, lang, member, current_scope); if (!member_tags) member_tags = find_scope_members_all(tags, theWorkspace->global_tags, lang, member, current_scope); g_ptr_array_free(tags, TRUE); g_hash_table_destroy(info.includes); } if (member_tags) tm_tags_dedup(member_tags, sort_attr, FALSE); return member_tags; } #ifdef TM_DEBUG /* Dumps the workspace tree - useful for debugging */ void tm_workspace_dump(void) { guint i; #ifdef TM_DEBUG g_message("Dumping TagManager workspace tree.."); #endif for (i=0; i < theWorkspace->source_files->len; ++i) { TMSourceFile *source_file = theWorkspace->source_files->pdata[i]; fprintf(stderr, "%s", source_file->file_name); } } #endif /* TM_DEBUG */ geany-2.0/src/tagmanager/tm_workspace.h0000644000175000017500000000541314514252267015156 00000000000000/* * * Copyright (c) 2001-2002, Biswapesh Chattopadhyay * Copyright 2005 The Geany contributors * * This source code is released for free distribution under the terms of the * GNU General Public License. * */ #ifndef TM_WORKSPACE_H #define TM_WORKSPACE_H #include #include "tm_tag.h" G_BEGIN_DECLS /** The Tag Manager Workspace. This is a singleton object containing a list * of individual source files. There is also a global tag list * which can be loaded or created. This contains global tags gleaned from * /usr/include, etc. and should be used for autocompletion, calltips, etc. **/ typedef struct TMWorkspace { GPtrArray *global_tags; /**< Global tags loaded at startup. @elementtype{TMTag} */ GPtrArray *source_files; /**< An array of TMSourceFile pointers. @elementtype{TMSourceFile} */ GPtrArray *tags_array; /**< Sorted tags from all source files (just pointers to source file tags, the tag objects are owned by the source files). @elementtype{TMTag} */ GPtrArray *typename_array; /* Typename tags for syntax highlighting (pointers owned by source files) */ GPtrArray *global_typename_array; /* Like above for global tags */ GHashTable *source_file_map; /* File name -> GPtrArray map to speed up lookups based on file name */ } TMWorkspace; void tm_workspace_add_source_file(TMSourceFile *source_file); void tm_workspace_remove_source_file(TMSourceFile *source_file); void tm_workspace_add_source_files(GPtrArray *source_files); void tm_workspace_remove_source_files(GPtrArray *source_files); #ifdef GEANY_PRIVATE const TMWorkspace *tm_get_workspace(void); gboolean tm_workspace_load_global_tags(const char *tags_file, TMParserType mode); gboolean tm_workspace_create_global_tags(const char *pre_process, const char **includes, int includes_count, const char *tags_file, TMParserType lang); GPtrArray *tm_workspace_find(const char *name, const char *scope, TMTagType type, TMTagAttrType *attrs, TMParserType lang); GPtrArray *tm_workspace_find_prefix(const char *prefix, TMSourceFile *current_file, guint current_line, const gchar *current_scope, guint max_num); GPtrArray *tm_workspace_find_scope_members (TMSourceFile *source_file, const char *name, gboolean function, gboolean member, const gchar *current_scope, guint current_line, gboolean search_namespace); void tm_workspace_add_source_file_noupdate(TMSourceFile *source_file); void tm_workspace_update_source_file_buffer(TMSourceFile *source_file, guchar* text_buf, gsize buf_size); void tm_workspace_free(void); gboolean tm_workspace_is_autocomplete_tag(TMTag *tag, TMSourceFile *current_file, guint current_line, const gchar *current_scope); #ifdef TM_DEBUG void tm_workspace_dump(void); #endif /* TM_DEBUG */ #endif /* GEANY_PRIVATE */ G_END_DECLS #endif /* TM_WORKSPACE_H */ geany-2.0/src/pluginprivate.h0000644000175000017500000000575014514252267013247 00000000000000/* * pluginprivate.h - this file is part of Geany, a fast and lightweight IDE * * Copyright 2009 The Geany contributors * * This program 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; either version 2 of the License, or * (at your option) any later version. * * This program 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef GEANY_PLUGIN_PRIVATE_H #define GEANY_PLUGIN_PRIVATE_H 1 #include "plugindata.h" #include "ui_utils.h" /* GeanyAutoSeparator */ #include "keybindings.h" /* GeanyKeyGroup */ G_BEGIN_DECLS typedef struct SignalConnection { GObject *object; gulong handler_id; } SignalConnection; typedef enum _LoadedFlags { LOADED_OK = 0x01, IS_LEGACY = 0x02, LOAD_DATA = 0x04, } LoadedFlags; typedef struct GeanyPluginPrivate Plugin; /* shorter alias */ typedef struct GeanyPluginPrivate { gchar *filename; /* plugin filename (/path/libname.so) */ PluginInfo info; /* plugin name, description, etc */ GeanyPlugin public; /* fields the plugin can read */ GeanyPluginFuncs cbs; /* Callbacks set by geany_plugin_register() */ void (*configure_single) (GtkWidget *parent); /* plugin configure dialog, optional and deprecated */ /* extra stuff */ GeanyKeyGroup *key_group; GeanyAutoSeparator toolbar_separator; GArray *signal_ids; /* SignalConnection's to disconnect when unloading */ GList *sources; /* GSources to destroy when unloading */ gpointer cb_data; /* user data passed back to functions in GeanyPluginFuncs */ GDestroyNotify cb_data_destroy; /* called when the plugin is unloaded, for cb_data */ LoadedFlags flags; /* bit-or of LoadedFlags */ /* proxy plugin support */ GeanyProxyFuncs proxy_cbs; Plugin *proxy; /* The proxy that handles this plugin */ gpointer proxy_data; /* Data passed to the proxy hooks of above proxy, so * this gives the proxy a pointer to each plugin */ gint proxied_count; /* count of active plugins this provides a proxy for * (a count because of possibly nested proxies) */ } GeanyPluginPrivate; #define PLUGIN_LOADED_OK(p) (((p)->flags & LOADED_OK) != 0) #define PLUGIN_IS_LEGACY(p) (((p)->flags & IS_LEGACY) != 0) #define PLUGIN_HAS_LOAD_DATA(p) (((p)->flags & LOAD_DATA) != 0) void plugin_watch_object(Plugin *plugin, gpointer object); void plugin_make_resident(Plugin *plugin); gpointer plugin_get_module_symbol(Plugin *plugin, const gchar *sym); G_END_DECLS #endif /* GEANY_PLUGIN_PRIVATE_H */ geany-2.0/src/app.h0000644000175000017500000000353214514252267011132 00000000000000/* * app.h - this file is part of Geany, a fast and lightweight IDE * * Copyright 2005 The Geany contributors * * This program 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; either version 2 of the License, or * (at your option) any later version. * * This program 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /** * @file app.h * Contains the GeanyApp. */ #ifndef GEANY_APP_H #define GEANY_APP_H 1 #include "tm_workspace.h" #include "project.h" #include G_BEGIN_DECLS /** Important application fields. */ typedef struct GeanyApp { gboolean debug_mode; /**< @c TRUE if debug messages should be printed. */ /** User configuration directory, usually @c ~/.config/geany. * This is a full path read by @ref utils_get_real_path(). * @note Plugin configuration files should be saved as: * @code g_build_path(G_DIR_SEPARATOR_S, geany->app->configdir, "plugins", "pluginname", * "file.conf", NULL); @endcode */ gchar *configdir; gchar *datadir; gchar *docdir; const TMWorkspace *tm_workspace; /**< TagManager workspace/session tags. */ struct GeanyProject *project; /**< Currently active project or @c NULL if none is open. */ } GeanyApp; #ifdef GEANY_PRIVATE extern GeanyApp *app; #endif /* GEANY_PRIVATE */ G_END_DECLS #endif /* GEANY_APP_H */ geany-2.0/src/sciwrappers.h0000644000175000017500000002600614514252267012715 00000000000000/* * sciwrappers.h - this file is part of Geany, a fast and lightweight IDE * * Copyright 2005 The Geany contributors * * This program 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; either version 2 of the License, or * (at your option) any later version. * * This program 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef GEANY_SCI_WRAPPERS_H #define GEANY_SCI_WRAPPERS_H 1 #include "geany.h" /* for GEANY_DEPRECATED */ #include "gtkcompat.h" /* Needed by ScintillaWidget.h */ #include "Scintilla.h" /* Needed by ScintillaWidget.h */ #include "ScintillaWidget.h" /* for ScintillaObject */ G_BEGIN_DECLS #ifdef GEANY_PRIVATE # ifndef NDEBUG # define SSM(s, m, w, l) sci_send_message_internal(__FILE__, __LINE__, s, m, w, l) sptr_t sci_send_message_internal (const gchar *file, guint line, ScintillaObject *sci, guint msg, uptr_t wparam, sptr_t lparam); # else # define SSM(s, m, w, l) scintilla_send_message(s, m, w, l) # endif #endif void sci_set_text (ScintillaObject *sci, const gchar *text); gboolean sci_has_selection (ScintillaObject *sci); void sci_end_undo_action (ScintillaObject *sci); void sci_start_undo_action (ScintillaObject *sci); void sci_set_marker_at_line (ScintillaObject *sci, gint line_number, gint marker); void sci_delete_marker_at_line (ScintillaObject *sci, gint line_number, gint marker); gboolean sci_is_marker_set_at_line (ScintillaObject *sci, gint line, gint marker); gint sci_get_col_from_position (ScintillaObject *sci, gint position); gint sci_get_line_from_position (ScintillaObject *sci, gint position); gint sci_get_position_from_line (ScintillaObject *sci, gint line); gint sci_get_current_position (ScintillaObject *sci); void sci_set_current_position (ScintillaObject *sci, gint position, gboolean scroll_to_caret); gint sci_get_selection_start (ScintillaObject *sci); gint sci_get_selection_end (ScintillaObject *sci); void sci_replace_sel (ScintillaObject *sci, const gchar *text); gint sci_get_selection_mode (ScintillaObject *sci); void sci_set_selection_mode (ScintillaObject *sci, gint mode); void sci_set_selection_start (ScintillaObject *sci, gint position); void sci_set_selection_end (ScintillaObject *sci, gint position); gint sci_get_length (ScintillaObject *sci); gchar* sci_get_contents (ScintillaObject *sci, gint buffer_len); gint sci_get_selected_text_length2(ScintillaObject *sci); gchar* sci_get_selection_contents (ScintillaObject *sci); gchar* sci_get_line (ScintillaObject *sci, gint line_num); gint sci_get_line_length (ScintillaObject *sci, gint line); gint sci_get_line_count (ScintillaObject *sci); gint sci_get_line_end_position (ScintillaObject *sci, gint line); gboolean sci_get_line_is_visible (ScintillaObject *sci, gint line); void sci_ensure_line_is_visible (ScintillaObject *sci, gint line); gint sci_get_tab_width (ScintillaObject *sci); gchar sci_get_char_at (ScintillaObject *sci, gint pos); void sci_scroll_caret (ScintillaObject *sci); gint sci_find_text (ScintillaObject *sci, gint flags, struct Sci_TextToFind *ttf); void sci_set_font (ScintillaObject *sci, gint style, const gchar *font, gint size); void sci_goto_line (ScintillaObject *sci, gint line, gboolean unfold); gint sci_get_style_at (ScintillaObject *sci, gint position); gchar* sci_get_contents_range (ScintillaObject *sci, gint start, gint end); void sci_insert_text (ScintillaObject *sci, gint pos, const gchar *text); void sci_set_target_start (ScintillaObject *sci, gint start); void sci_set_target_end (ScintillaObject *sci, gint end); gint sci_replace_target (ScintillaObject *sci, const gchar *text, gboolean regex); gint sci_get_lexer (ScintillaObject *sci); void sci_send_command (ScintillaObject *sci, gint cmd); gint sci_get_current_line (ScintillaObject *sci); void sci_indicator_set (ScintillaObject *sci, gint indic); void sci_indicator_clear (ScintillaObject *sci, gint pos, gint len); void sci_set_line_indentation (ScintillaObject *sci, gint line, gint indent); gint sci_get_line_indentation (ScintillaObject *sci, gint line); gint sci_find_matching_brace (ScintillaObject *sci, gint pos); #ifndef GEANY_DISABLE_DEPRECATED void sci_get_text (ScintillaObject *sci, gint len, gchar *text) GEANY_DEPRECATED_FOR(sci_get_contents); void sci_get_selected_text (ScintillaObject *sci, gchar *text) GEANY_DEPRECATED_FOR(sci_get_selection_contents); void sci_get_text_range (ScintillaObject *sci, gint start, gint end, gchar *text) GEANY_DEPRECATED_FOR(sci_get_contents_range); gint sci_get_selected_text_length(ScintillaObject *sci) GEANY_DEPRECATED_FOR(sci_get_selected_text_length2); #endif /* GEANY_DISABLE_DEPRECATED */ #ifdef GEANY_PRIVATE gchar* sci_get_string (ScintillaObject *sci, guint msg, gulong wParam); void sci_set_line_numbers (ScintillaObject *sci, gboolean set); void sci_set_mark_long_lines (ScintillaObject *sci, gint type, gint column, const gchar *color); void sci_add_text (ScintillaObject *sci, const gchar *text); gboolean sci_can_redo (ScintillaObject *sci); gboolean sci_can_undo (ScintillaObject *sci); void sci_undo (ScintillaObject *sci); void sci_redo (ScintillaObject *sci); void sci_empty_undo_buffer (ScintillaObject *sci); gboolean sci_is_modified (ScintillaObject *sci); void sci_set_visible_eols (ScintillaObject *sci, gboolean set); void sci_set_lines_wrapped (ScintillaObject *sci, gboolean set); void sci_set_visible_white_spaces(ScintillaObject *sci, gboolean set); void sci_convert_eols (ScintillaObject *sci, gint eolmode); gint sci_get_eol_mode (ScintillaObject *sci); void sci_set_eol_mode (ScintillaObject *sci, gint eolmode); void sci_set_eol_representation_characters(ScintillaObject *sci, gint new_eolmode); void sci_zoom_in (ScintillaObject *sci); void sci_zoom_out (ScintillaObject *sci); void sci_zoom_off (ScintillaObject *sci); void sci_toggle_marker_at_line (ScintillaObject *sci, gint line, gint marker); gint sci_marker_next (ScintillaObject *sci, gint line, gint marker_mask, gboolean wrap); gint sci_marker_previous (ScintillaObject *sci, gint line, gint marker_mask, gboolean wrap); gint sci_get_position_from_col (ScintillaObject *sci, gint line, gint col); void sci_set_current_line (ScintillaObject *sci, gint line); gint sci_get_cursor_virtual_space(ScintillaObject *sci); void sci_cut (ScintillaObject *sci); void sci_copy (ScintillaObject *sci); void sci_paste (ScintillaObject *sci); void sci_clear (ScintillaObject *sci); gint sci_get_pos_at_line_sel_start(ScintillaObject*sci, gint line); gint sci_get_pos_at_line_sel_end (ScintillaObject *sci, gint line); void sci_set_selection (ScintillaObject *sci, gint anchorPos, gint currentPos); gint sci_get_position_from_xy (ScintillaObject *sci, gint x, gint y, gboolean nearby); void sci_set_undo_collection (ScintillaObject *sci, gboolean set); void sci_toggle_fold (ScintillaObject *sci, gint line); gint sci_get_fold_level (ScintillaObject *sci, gint line); gint sci_get_fold_parent (ScintillaObject *sci, gint start_line); void sci_set_folding_margin_visible (ScintillaObject *sci, gboolean set); gboolean sci_get_fold_expanded (ScintillaObject *sci, gint line); void sci_colourise (ScintillaObject *sci, gint start, gint end); void sci_clear_all (ScintillaObject *sci); gint sci_get_end_styled (ScintillaObject *sci); void sci_set_tab_width (ScintillaObject *sci, gint width); void sci_set_savepoint (ScintillaObject *sci); void sci_set_indentation_guides (ScintillaObject *sci, gint mode); void sci_use_popup (ScintillaObject *sci, gboolean enable); void sci_goto_pos (ScintillaObject *sci, gint pos, gboolean unfold); void sci_set_search_anchor (ScintillaObject *sci); void sci_set_anchor (ScintillaObject *sci, gint pos); void sci_scroll_columns (ScintillaObject *sci, gint columns); gint sci_search_next (ScintillaObject *sci, gint flags, const gchar *text); gint sci_search_prev (ScintillaObject *sci, gint flags, const gchar *text); void sci_marker_delete_all (ScintillaObject *sci, gint marker); void sci_set_symbol_margin (ScintillaObject *sci, gboolean set); void sci_set_codepage (ScintillaObject *sci, gint cp); void sci_clear_cmdkey (ScintillaObject *sci, gint key); void sci_assign_cmdkey (ScintillaObject *sci, gint key, gint command); void sci_selection_duplicate (ScintillaObject *sci); void sci_line_duplicate (ScintillaObject *sci); void sci_set_keywords (ScintillaObject *sci, guint k, const gchar *text); void sci_set_lexer (ScintillaObject *sci, guint lexer_id); void sci_set_readonly (ScintillaObject *sci, gboolean readonly); gint sci_get_lines_selected (ScintillaObject *sci); gint sci_get_first_visible_line (ScintillaObject *sci); void sci_indicator_fill (ScintillaObject *sci, gint pos, gint len); void sci_select_all (ScintillaObject *sci); gint sci_get_line_indent_position(ScintillaObject *sci, gint line); void sci_set_autoc_max_height (ScintillaObject *sci, gint val); gint sci_get_overtype (ScintillaObject *sci); void sci_set_tab_indents (ScintillaObject *sci, gboolean set); void sci_set_use_tabs (ScintillaObject *sci, gboolean set); void sci_set_scrollbar_mode (ScintillaObject *sci, gboolean visible); void sci_set_caret_policy_x (ScintillaObject *sci, gint policy, gint slop); void sci_set_caret_policy_y (ScintillaObject *sci, gint policy, gint slop); void sci_set_scroll_stop_at_last_line (ScintillaObject *sci, gboolean set); void sci_cancel (ScintillaObject *sci); gint sci_get_position_after (ScintillaObject *sci, gint start); gint sci_word_start_position (ScintillaObject *sci, gint position, gboolean onlyWordCharacters); gint sci_word_end_position (ScintillaObject *sci, gint position, gboolean onlyWordCharacters); void sci_lines_join (ScintillaObject *sci); gint sci_text_width (ScintillaObject *sci, gint styleNumber, const gchar *text); void sci_move_selected_lines_down (ScintillaObject *sci); void sci_move_selected_lines_up (ScintillaObject *sci); void sci_set_font_fractional (ScintillaObject *sci, gint style, const gchar *font, gdouble size); #endif /* GEANY_PRIVATE */ G_END_DECLS #endif /* GEANY_SCI_WRAPPERS_H */ geany-2.0/src/encodings.h0000644000175000017500000000704514514252267012326 00000000000000/* * encodings.h - this file is part of Geany, a fast and lightweight IDE * * Copyright 2005 The Geany contributors * * This program 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; either version 2 of the License, or * (at your option) any later version. * * This program 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /** * @file encodings.h * Encoding conversion and Byte Order Mark (BOM) handling. **/ /* * Modified by the gedit Team, 2002. See the gedit AUTHORS file for a * list of people on the gedit Team. * See the gedit ChangeLog files for a list of changes. */ /* Stolen from anjuta */ #ifndef GEANY_ENCODINGS_H #define GEANY_ENCODINGS_H 1 #include "gtkcompat.h" G_BEGIN_DECLS /* * The original versions of the following tables are taken from profterm * * Copyright (C) 2002 Red Hat, Inc. */ /** List of known and supported encodings. */ typedef enum { GEANY_ENCODING_ISO_8859_1, GEANY_ENCODING_ISO_8859_2, GEANY_ENCODING_ISO_8859_3, GEANY_ENCODING_ISO_8859_4, GEANY_ENCODING_ISO_8859_5, GEANY_ENCODING_ISO_8859_6, GEANY_ENCODING_ISO_8859_7, GEANY_ENCODING_ISO_8859_8, GEANY_ENCODING_ISO_8859_8_I, GEANY_ENCODING_ISO_8859_9, GEANY_ENCODING_ISO_8859_10, GEANY_ENCODING_ISO_8859_13, GEANY_ENCODING_ISO_8859_14, GEANY_ENCODING_ISO_8859_15, GEANY_ENCODING_ISO_8859_16, GEANY_ENCODING_UTF_7, GEANY_ENCODING_UTF_8, GEANY_ENCODING_UTF_16LE, GEANY_ENCODING_UTF_16BE, GEANY_ENCODING_UCS_2LE, GEANY_ENCODING_UCS_2BE, GEANY_ENCODING_UTF_32LE, GEANY_ENCODING_UTF_32BE, GEANY_ENCODING_ARMSCII_8, GEANY_ENCODING_BIG5, GEANY_ENCODING_BIG5_HKSCS, GEANY_ENCODING_CP_866, GEANY_ENCODING_EUC_JP, GEANY_ENCODING_EUC_KR, GEANY_ENCODING_EUC_TW, GEANY_ENCODING_GB18030, GEANY_ENCODING_GB2312, GEANY_ENCODING_GBK, GEANY_ENCODING_GEOSTD8, GEANY_ENCODING_HZ, GEANY_ENCODING_IBM_850, GEANY_ENCODING_IBM_852, GEANY_ENCODING_IBM_855, GEANY_ENCODING_IBM_857, GEANY_ENCODING_IBM_862, GEANY_ENCODING_IBM_864, GEANY_ENCODING_ISO_2022_JP, GEANY_ENCODING_ISO_2022_KR, GEANY_ENCODING_ISO_IR_111, GEANY_ENCODING_JOHAB, GEANY_ENCODING_KOI8_R, GEANY_ENCODING_KOI8_U, GEANY_ENCODING_SHIFT_JIS, GEANY_ENCODING_TCVN, GEANY_ENCODING_TIS_620, GEANY_ENCODING_UHC, GEANY_ENCODING_VISCII, GEANY_ENCODING_WINDOWS_1250, GEANY_ENCODING_WINDOWS_1251, GEANY_ENCODING_WINDOWS_1252, GEANY_ENCODING_WINDOWS_1253, GEANY_ENCODING_WINDOWS_1254, GEANY_ENCODING_WINDOWS_1255, GEANY_ENCODING_WINDOWS_1256, GEANY_ENCODING_WINDOWS_1257, GEANY_ENCODING_WINDOWS_1258, GEANY_ENCODING_NONE, GEANY_ENCODING_CP_932, GEANY_ENCODINGS_MAX } GeanyEncodingIndex; gchar *encodings_convert_to_utf8(const gchar *buffer, gssize size, gchar **used_encoding); /* Converts a string from the given charset to UTF-8. * If fast is set, no further checks are performed. */ gchar *encodings_convert_to_utf8_from_charset(const gchar *buffer, gssize size, const gchar *charset, gboolean fast); const gchar* encodings_get_charset_from_index(gint idx); G_END_DECLS #endif /* GEANY_ENCODINGS_H */ geany-2.0/src/tools.c0000644000175000017500000006422614514252267011514 00000000000000/* * tools.c - this file is part of Geany, a fast and lightweight IDE * * Copyright 2006 The Geany contributors * * This program 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; either version 2 of the License, or * (at your option) any later version. * * This program 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /* * Miscellaneous code for the built-in Tools menu items, and custom command code. * For Plugins code see plugins.c. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include "tools.h" #include "document.h" #include "keybindings.h" #include "sciwrappers.h" #include "spawn.h" #include "support.h" #include "ui_utils.h" #include "utils.h" #include #include #include #include #include enum { CC_COLUMN_ID, CC_COLUMN_STATUS, CC_COLUMN_TOOLTIP, CC_COLUMN_CMD, CC_COLUMN_LABEL, CC_COLUMN_COUNT }; /* custom commands code*/ struct cc_dialog { guint count; GtkWidget *view; GtkTreeViewColumn *edit_column; GtkListStore *store; GtkTreeSelection *selection; GtkWidget *button_add; GtkWidget *button_remove; GtkWidget *button_up; GtkWidget *button_down; }; /* update STATUS and TOOLTIP columns according to cmd */ static void cc_dialog_update_row_status(GtkListStore *store, GtkTreeIter *iter, const gchar *cmd) { GError *err = NULL; const gchar *stock_id = GTK_STOCK_NO; gchar *tooltip = NULL; if (EMPTY(cmd) || spawn_check_command(cmd, TRUE, &err)) stock_id = GTK_STOCK_YES; else { tooltip = g_strdup_printf(_("Invalid command: %s"), err->message); g_error_free(err); } gtk_list_store_set(store, iter, CC_COLUMN_STATUS, stock_id, CC_COLUMN_TOOLTIP, tooltip, -1); g_free(tooltip); } /* adds a new row for custom command @p idx, or an new empty one if < 0 */ static void cc_dialog_add_command(struct cc_dialog *cc, gint idx, gboolean start_editing) { GtkTreeIter iter; const gchar *cmd = NULL; const gchar *label = NULL; guint id = cc->count; if (idx >= 0) { cmd = ui_prefs.custom_commands[idx]; label = ui_prefs.custom_commands_labels[idx]; } cc->count++; gtk_list_store_append(cc->store, &iter); gtk_list_store_set(cc->store, &iter, CC_COLUMN_ID, id, CC_COLUMN_CMD, cmd, CC_COLUMN_LABEL, label, -1); cc_dialog_update_row_status(cc->store, &iter, cmd); if (start_editing) { GtkTreePath *path; gtk_widget_grab_focus(cc->view); path = gtk_tree_model_get_path(GTK_TREE_MODEL(cc->store), &iter); gtk_tree_view_set_cursor(GTK_TREE_VIEW(cc->view), path, cc->edit_column, TRUE); gtk_tree_path_free(path); } } static void cc_on_dialog_add_clicked(GtkButton *button, struct cc_dialog *cc) { cc_dialog_add_command(cc, -1, TRUE); } static void scroll_to_cursor(GtkTreeView *view) { GtkTreePath *path; GtkTreeViewColumn *column; gtk_tree_view_get_cursor(view, &path, &column); if (path) { gtk_tree_view_scroll_to_cell(view, path, column, FALSE, 1.0, 1.0); gtk_tree_path_free(path); } } static void cc_on_dialog_remove_clicked(GtkButton *button, struct cc_dialog *cc) { GtkTreeIter iter; if (gtk_tree_selection_get_selected(cc->selection, NULL, &iter)) { gtk_list_store_remove(cc->store, &iter); scroll_to_cursor(GTK_TREE_VIEW(cc->view)); } } static void cc_on_dialog_move_up_clicked(GtkButton *button, struct cc_dialog *cc) { GtkTreeIter iter; if (gtk_tree_selection_get_selected(cc->selection, NULL, &iter)) { GtkTreePath *path; GtkTreeIter prev; path = gtk_tree_model_get_path(GTK_TREE_MODEL(cc->store), &iter); if (gtk_tree_path_prev(path) && gtk_tree_model_get_iter(GTK_TREE_MODEL(cc->store), &prev, path)) { gtk_list_store_move_before(cc->store, &iter, &prev); scroll_to_cursor(GTK_TREE_VIEW(cc->view)); } gtk_tree_path_free(path); } } static void cc_on_dialog_move_down_clicked(GtkButton *button, struct cc_dialog *cc) { GtkTreeIter iter; if (gtk_tree_selection_get_selected(cc->selection, NULL, &iter)) { GtkTreeIter next = iter; if (gtk_tree_model_iter_next(GTK_TREE_MODEL(cc->store), &next)) { gtk_list_store_move_after(cc->store, &iter, &next); scroll_to_cursor(GTK_TREE_VIEW(cc->view)); } } } /* Executes command (which should include all necessary command line args) and passes the current * selection through the standard input of command. The whole output of command replaces the * current selection. */ void tools_execute_custom_command(GeanyDocument *doc, const gchar *command) { GError *error = NULL; gchar *sel; SpawnWriteData input; GString *output; GString *errors; gint status; g_return_if_fail(doc != NULL && command != NULL); if (! sci_has_selection(doc->editor->sci)) editor_select_lines(doc->editor, FALSE); sel = sci_get_selection_contents(doc->editor->sci); input.ptr = sel; input.size = strlen(sel); output = g_string_sized_new(256); errors = g_string_new(NULL); ui_set_statusbar(TRUE, _("Passing data and executing custom command: %s"), command); if (spawn_sync(NULL, command, NULL, NULL, &input, output, errors, &status, &error)) { if (errors->len > 0) { g_warning("%s: %s\n", command, errors->str); ui_set_statusbar(TRUE, _("The executed custom command returned an error. " "Your selection was not changed. Error message: %s"), errors->str); } else if (!SPAWN_WIFEXITED(status) || SPAWN_WEXITSTATUS(status) != EXIT_SUCCESS) { /* TODO maybe include the exit code in the error message */ ui_set_statusbar(TRUE, _("The executed custom command exited with an unsuccessful exit code.")); } else { /* Command completed successfully */ sci_replace_sel(doc->editor->sci, output->str); } } else { ui_set_statusbar(TRUE, _("Cannot execute custom command \"%s\": %s. " "Check the path setting in Custom Commands."), command, error->message); g_error_free(error); } g_string_free(output, TRUE); g_string_free(errors, TRUE); g_free(sel); } static void cc_dialog_on_command_edited(GtkCellRendererText *renderer, gchar *path, gchar *text, struct cc_dialog *cc) { GtkTreeIter iter; gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(cc->store), &iter, path); gtk_list_store_set(cc->store, &iter, CC_COLUMN_CMD, text, -1); cc_dialog_update_row_status(cc->store, &iter, text); } static void cc_dialog_on_label_edited(GtkCellRendererText *renderer, gchar *path, gchar *text, struct cc_dialog *cc) { GtkTreeIter iter; gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(cc->store), &iter, path); gtk_list_store_set(cc->store, &iter, CC_COLUMN_LABEL, text, -1); } /* re-compute IDs to reflect the current store state */ static void cc_dialog_update_ids(struct cc_dialog *cc) { GtkTreeIter iter; cc->count = 1; if (! gtk_tree_model_get_iter_first(GTK_TREE_MODEL(cc->store), &iter)) return; do { gtk_list_store_set(cc->store, &iter, CC_COLUMN_ID, cc->count, -1); cc->count++; } while (gtk_tree_model_iter_next(GTK_TREE_MODEL(cc->store), &iter)); } /* update sensitiveness of the buttons according to the selection */ static void cc_dialog_update_sensitive(struct cc_dialog *cc) { GtkTreeIter iter; gboolean has_selection = FALSE; gboolean first_selected = FALSE; gboolean last_selected = FALSE; if ((has_selection = gtk_tree_selection_get_selected(cc->selection, NULL, &iter))) { GtkTreePath *path; GtkTreePath *copy; path = gtk_tree_model_get_path(GTK_TREE_MODEL(cc->store), &iter); copy = gtk_tree_path_copy(path); first_selected = ! gtk_tree_path_prev(copy); gtk_tree_path_free(copy); gtk_tree_path_next(path); last_selected = ! gtk_tree_model_get_iter(GTK_TREE_MODEL(cc->store), &iter, path); gtk_tree_path_free(path); } gtk_widget_set_sensitive(cc->button_remove, has_selection); gtk_widget_set_sensitive(cc->button_up, has_selection && ! first_selected); gtk_widget_set_sensitive(cc->button_down, has_selection && ! last_selected); } static void cc_dialog_on_tree_selection_changed(GtkTreeSelection *selection, struct cc_dialog *cc) { cc_dialog_update_sensitive(cc); } static void cc_dialog_on_row_inserted(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, struct cc_dialog *cc) { cc_dialog_update_ids(cc); cc_dialog_update_sensitive(cc); } static void cc_dialog_on_row_deleted(GtkTreeModel *model, GtkTreePath *path, struct cc_dialog *cc) { cc_dialog_update_ids(cc); cc_dialog_update_sensitive(cc); } static void cc_dialog_on_rows_reordered(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer new_order, struct cc_dialog *cc) { cc_dialog_update_ids(cc); cc_dialog_update_sensitive(cc); } static void cc_show_dialog_custom_commands(void) { GtkWidget *dialog, *label, *vbox, *scroll, *buttonbox; GtkCellRenderer *renderer; GtkTreeViewColumn *column; guint i; struct cc_dialog cc; dialog = gtk_dialog_new_with_buttons(_("Set Custom Commands"), GTK_WINDOW(main_widgets.window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, NULL); gtk_window_set_default_size(GTK_WINDOW(dialog), 300, 300); /* give a reasonable minimal default size */ vbox = ui_dialog_vbox_new(GTK_DIALOG(dialog)); gtk_box_set_spacing(GTK_BOX(vbox), 6); gtk_widget_set_name(dialog, "GeanyDialog"); label = gtk_label_new(_("You can send the current selection to any of these commands and the output of the command replaces the current selection.")); gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); cc.count = 1; cc.store = gtk_list_store_new(CC_COLUMN_COUNT, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING); cc.view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(cc.store)); ui_tree_view_set_tooltip_text_column(GTK_TREE_VIEW(cc.view), CC_COLUMN_TOOLTIP); gtk_tree_view_set_reorderable(GTK_TREE_VIEW(cc.view), TRUE); cc.selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(cc.view)); /* ID column */ renderer = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes(_("ID"), renderer, "text", CC_COLUMN_ID, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(cc.view), column); /* command column, holding status and command display */ column = g_object_new(GTK_TYPE_TREE_VIEW_COLUMN, "title", _("Command"), "expand", TRUE, "resizable", TRUE, NULL); renderer = gtk_cell_renderer_pixbuf_new(); gtk_tree_view_column_pack_start(column, renderer, FALSE); gtk_tree_view_column_set_attributes(column, renderer, "stock-id", CC_COLUMN_STATUS, NULL); renderer = gtk_cell_renderer_text_new(); g_object_set(renderer, "editable", TRUE, "ellipsize", PANGO_ELLIPSIZE_END, NULL); g_signal_connect(renderer, "edited", G_CALLBACK(cc_dialog_on_command_edited), &cc); gtk_tree_view_column_pack_start(column, renderer, TRUE); gtk_tree_view_column_set_attributes(column, renderer, "text", CC_COLUMN_CMD, NULL); cc.edit_column = column; gtk_tree_view_append_column(GTK_TREE_VIEW(cc.view), column); /* label column */ renderer = gtk_cell_renderer_text_new(); g_object_set(renderer, "editable", TRUE, "ellipsize", PANGO_ELLIPSIZE_END, NULL); g_signal_connect(renderer, "edited", G_CALLBACK(cc_dialog_on_label_edited), &cc); column = gtk_tree_view_column_new_with_attributes(_("Label"), renderer, "text", CC_COLUMN_LABEL, NULL); g_object_set(column, "expand", TRUE, "resizable", TRUE, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(cc.view), column); scroll = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scroll), GTK_SHADOW_IN); gtk_container_add(GTK_CONTAINER(scroll), cc.view); gtk_box_pack_start(GTK_BOX(vbox), scroll, TRUE, TRUE, 0); if (ui_prefs.custom_commands != NULL) { GtkTreeIter iter; guint len = g_strv_length(ui_prefs.custom_commands); for (i = 0; i < len; i++) { if (EMPTY(ui_prefs.custom_commands[i])) continue; /* skip empty fields */ cc_dialog_add_command(&cc, i, FALSE); } /* focus the first row if any */ if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(cc.store), &iter)) { GtkTreePath *path = gtk_tree_model_get_path(GTK_TREE_MODEL(cc.store), &iter); gtk_tree_view_set_cursor(GTK_TREE_VIEW(cc.view), path, cc.edit_column, FALSE); gtk_tree_path_free(path); } } buttonbox = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL); gtk_box_set_spacing(GTK_BOX(buttonbox), 6); gtk_box_pack_start(GTK_BOX(vbox), buttonbox, FALSE, FALSE, 0); cc.button_add = gtk_button_new_from_stock(GTK_STOCK_ADD); g_signal_connect(cc.button_add, "clicked", G_CALLBACK(cc_on_dialog_add_clicked), &cc); gtk_container_add(GTK_CONTAINER(buttonbox), cc.button_add); cc.button_remove = gtk_button_new_from_stock(GTK_STOCK_REMOVE); g_signal_connect(cc.button_remove, "clicked", G_CALLBACK(cc_on_dialog_remove_clicked), &cc); gtk_container_add(GTK_CONTAINER(buttonbox), cc.button_remove); cc.button_up = gtk_button_new_from_stock(GTK_STOCK_GO_UP); g_signal_connect(cc.button_up, "clicked", G_CALLBACK(cc_on_dialog_move_up_clicked), &cc); gtk_container_add(GTK_CONTAINER(buttonbox), cc.button_up); cc.button_down = gtk_button_new_from_stock(GTK_STOCK_GO_DOWN); g_signal_connect(cc.button_down, "clicked", G_CALLBACK(cc_on_dialog_move_down_clicked), &cc); gtk_container_add(GTK_CONTAINER(buttonbox), cc.button_down); cc_dialog_update_sensitive(&cc); /* only connect the selection signal when all other cc_dialog fields are set */ g_signal_connect(cc.selection, "changed", G_CALLBACK(cc_dialog_on_tree_selection_changed), &cc); g_signal_connect(cc.store, "row-inserted", G_CALLBACK(cc_dialog_on_row_inserted), &cc); g_signal_connect(cc.store, "row-deleted", G_CALLBACK(cc_dialog_on_row_deleted), &cc); g_signal_connect(cc.store, "rows-reordered", G_CALLBACK(cc_dialog_on_rows_reordered), &cc); gtk_widget_show_all(vbox); if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { GSList *cmd_list = NULL; GSList *lbl_list = NULL; gint len = 0; gchar **commands = NULL; gchar **labels = NULL; GtkTreeIter iter; if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(cc.store), &iter)) { do { gchar *cmd; gchar *lbl; gtk_tree_model_get(GTK_TREE_MODEL(cc.store), &iter, CC_COLUMN_CMD, &cmd, CC_COLUMN_LABEL, &lbl, -1); if (!EMPTY(cmd)) { cmd_list = g_slist_prepend(cmd_list, cmd); lbl_list = g_slist_prepend(lbl_list, lbl); len++; } else { g_free(cmd); g_free(lbl); } } while (gtk_tree_model_iter_next(GTK_TREE_MODEL(cc.store), &iter)); } cmd_list = g_slist_reverse(cmd_list); lbl_list = g_slist_reverse(lbl_list); /* create a new null-terminated array but only if there is any commands defined */ if (len > 0) { gint j = 0; GSList *cmd_node, *lbl_node; commands = g_new(gchar*, len + 1); labels = g_new(gchar*, len + 1); /* walk commands and labels lists */ for (cmd_node = cmd_list, lbl_node = lbl_list; cmd_node != NULL; cmd_node = cmd_node->next, lbl_node = lbl_node->next) { commands[j] = (gchar*) cmd_node->data; labels[j] = (gchar*) lbl_node->data; j++; } /* null-terminate the arrays */ commands[j] = NULL; labels[j] = NULL; } /* set the new arrays */ g_strfreev(ui_prefs.custom_commands); ui_prefs.custom_commands = commands; g_strfreev(ui_prefs.custom_commands_labels); ui_prefs.custom_commands_labels = labels; /* rebuild the menu items */ tools_create_insert_custom_command_menu_items(); g_slist_free(cmd_list); g_slist_free(lbl_list); } gtk_widget_destroy(dialog); } static void cc_on_custom_command_activate(GtkMenuItem *menuitem, gpointer user_data) { GeanyDocument *doc = document_get_current(); gint command_idx; g_return_if_fail(DOC_VALID(doc)); command_idx = GPOINTER_TO_INT(user_data); if (ui_prefs.custom_commands == NULL || command_idx < 0 || command_idx > (gint) g_strv_length(ui_prefs.custom_commands)) { cc_show_dialog_custom_commands(); return; } /* send it through the command and when the command returned the output the current selection * will be replaced */ tools_execute_custom_command(doc, ui_prefs.custom_commands[command_idx]); } static void cc_insert_custom_command_items(GtkMenu *me, const gchar *label, const gchar *tooltip, gint idx) { GtkWidget *item; gint key_idx = -1; switch (idx) { case 0: key_idx = GEANY_KEYS_FORMAT_SENDTOCMD1; break; case 1: key_idx = GEANY_KEYS_FORMAT_SENDTOCMD2; break; case 2: key_idx = GEANY_KEYS_FORMAT_SENDTOCMD3; break; case 3: key_idx = GEANY_KEYS_FORMAT_SENDTOCMD4; break; case 4: key_idx = GEANY_KEYS_FORMAT_SENDTOCMD5; break; case 5: key_idx = GEANY_KEYS_FORMAT_SENDTOCMD6; break; case 6: key_idx = GEANY_KEYS_FORMAT_SENDTOCMD7; break; case 7: key_idx = GEANY_KEYS_FORMAT_SENDTOCMD8; break; case 8: key_idx = GEANY_KEYS_FORMAT_SENDTOCMD9; break; } item = gtk_menu_item_new_with_label(label); gtk_widget_set_tooltip_text(item, tooltip); if (key_idx != -1) { GeanyKeyBinding *kb = keybindings_lookup_item(GEANY_KEY_GROUP_FORMAT, key_idx); if (kb->key > 0) { gtk_widget_add_accelerator(item, "activate", gtk_accel_group_new(), kb->key, kb->mods, GTK_ACCEL_VISIBLE); } } gtk_container_add(GTK_CONTAINER(me), item); gtk_widget_show(item); g_signal_connect(item, "activate", G_CALLBACK(cc_on_custom_command_activate), GINT_TO_POINTER(idx)); } void tools_create_insert_custom_command_menu_items(void) { GtkMenu *menu_edit = GTK_MENU(ui_lookup_widget(main_widgets.window, "send_selection_to2_menu")); GtkWidget *item; GList *me_children, *node; /* first clean the menus to be able to rebuild them */ me_children = gtk_container_get_children(GTK_CONTAINER(menu_edit)); foreach_list(node, me_children) gtk_widget_destroy(GTK_WIDGET(node->data)); g_list_free(me_children); if (ui_prefs.custom_commands == NULL || g_strv_length(ui_prefs.custom_commands) == 0) { item = gtk_menu_item_new_with_label(_("No custom commands defined.")); gtk_container_add(GTK_CONTAINER(menu_edit), item); gtk_widget_set_sensitive(item, FALSE); gtk_widget_show(item); } else { guint i, len; gint idx = 0; len = g_strv_length(ui_prefs.custom_commands); for (i = 0; i < len; i++) { const gchar *label = ui_prefs.custom_commands_labels[i]; if (EMPTY(label)) label = ui_prefs.custom_commands[i]; if (!EMPTY(label)) /* skip empty items */ { cc_insert_custom_command_items(menu_edit, label, ui_prefs.custom_commands[i], idx); idx++; } } } /* separator and Set menu item */ item = gtk_separator_menu_item_new(); gtk_container_add(GTK_CONTAINER(menu_edit), item); gtk_widget_show(item); cc_insert_custom_command_items(menu_edit, _("Set Custom Commands"), NULL, -1); } /* (stolen from bluefish, thanks) * Returns number of characters, lines and words in the supplied gchar*. * Handles UTF-8 correctly. Input must be properly encoded UTF-8. * Words are defined as any characters grouped, separated with spaces. */ static void word_count(gchar *text, guint *chars, guint *lines, guint *words) { guint in_word = 0; gunichar utext; if (! text) return; /* politely refuse to operate on NULL */ *chars = *words = *lines = 0; while (*text != '\0') { (*chars)++; switch (*text) { case '\n': (*lines)++; /* fall through */ case '\r': case '\f': case '\t': case ' ': case '\v': mb_word_separator: if (in_word) { in_word = 0; (*words)++; } break; default: utext = g_utf8_get_char_validated(text, 2); /* This might be an utf-8 char */ if (g_unichar_isspace(utext)) /* Unicode encoded space? */ goto mb_word_separator; if (g_unichar_isgraph(utext)) /* Is this something printable? */ in_word = 1; break; } /* Even if the current char is 2 bytes, this will iterate correctly. */ text = g_utf8_next_char(text); } /* Capture last word, if there's no whitespace at the end of the file. */ if (in_word) (*words)++; /* We start counting line numbers from 1 */ if (*chars > 0) (*lines)++; } void tools_word_count(void) { GtkWidget *dialog, *label, *vbox, *table; GeanyDocument *doc; guint chars = 0, lines = 0, words = 0; gchar *text; const gchar *range; doc = document_get_current(); g_return_if_fail(doc != NULL); dialog = gtk_dialog_new_with_buttons(_("Word Count"), GTK_WINDOW(main_widgets.window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_CLOSE, GTK_RESPONSE_CANCEL, NULL); vbox = ui_dialog_vbox_new(GTK_DIALOG(dialog)); gtk_widget_set_name(dialog, "GeanyDialog"); if (sci_has_selection(doc->editor->sci)) { text = sci_get_selection_contents(doc->editor->sci); range = _("selection"); } else { text = sci_get_contents(doc->editor->sci, -1); range = _("whole document"); } word_count(text, &chars, &lines, &words); g_free(text); table = gtk_table_new(4, 2, FALSE); gtk_table_set_row_spacings(GTK_TABLE(table), 5); gtk_table_set_col_spacings(GTK_TABLE(table), 10); label = gtk_label_new(_("Range:")); gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); gtk_misc_set_alignment(GTK_MISC(label), 1, 0); label = gtk_label_new(range); gtk_table_attach(GTK_TABLE(table), label, 1, 2, 0, 1, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 20, 0); gtk_misc_set_alignment(GTK_MISC(label), 0, 0); label = gtk_label_new(_("Lines:")); gtk_table_attach(GTK_TABLE(table), label, 0, 1, 1, 2, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); gtk_misc_set_alignment(GTK_MISC(label), 1, 0); text = g_strdup_printf("%d", lines); label = gtk_label_new(text); gtk_table_attach(GTK_TABLE(table), label, 1, 2, 1, 2, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 20, 0); gtk_misc_set_alignment(GTK_MISC(label), 0, 0); g_free(text); label = gtk_label_new(_("Words:")); gtk_table_attach(GTK_TABLE(table), label, 0, 1, 2, 3, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); gtk_misc_set_alignment(GTK_MISC(label), 1, 0); text = g_strdup_printf("%d", words); label = gtk_label_new(text); gtk_table_attach(GTK_TABLE(table), label, 1, 2, 2, 3, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 20, 0); gtk_misc_set_alignment(GTK_MISC(label), 0, 0); g_free(text); label = gtk_label_new(_("Characters:")); gtk_table_attach(GTK_TABLE(table), label, 0, 1, 3, 4, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); gtk_misc_set_alignment(GTK_MISC(label), 1, 0); text = g_strdup_printf("%d", chars); label = gtk_label_new(text); gtk_table_attach(GTK_TABLE(table), label, 1, 2, 3, 4, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 20, 0); gtk_misc_set_alignment(GTK_MISC(label), 0, 0); g_free(text); gtk_container_add(GTK_CONTAINER(vbox), table); g_signal_connect(dialog, "response", G_CALLBACK(gtk_widget_destroy), dialog); g_signal_connect(dialog, "delete-event", G_CALLBACK(gtk_widget_destroy), dialog); gtk_widget_show_all(dialog); } /* * color dialog callbacks */ static void on_color_dialog_response(GtkDialog *dialog, gint response, gpointer user_data) { switch (response) { case GTK_RESPONSE_OK: gtk_widget_hide(ui_widgets.open_colorsel); /* fall through */ case GTK_RESPONSE_APPLY: { GdkColor color; GeanyDocument *doc = document_get_current(); gchar *hex; GtkWidget *colorsel; g_return_if_fail(doc != NULL); colorsel = gtk_color_selection_dialog_get_color_selection(GTK_COLOR_SELECTION_DIALOG(ui_widgets.open_colorsel)); gtk_color_selection_get_current_color(GTK_COLOR_SELECTION(colorsel), &color); hex = utils_get_hex_from_color(&color); editor_insert_color(doc->editor, hex); g_free(hex); break; } default: gtk_widget_hide(ui_widgets.open_colorsel); } } static void on_color_selection_change_palette_with_screen(GdkScreen *screen, const GdkColor *colors, gint n_colors) { GtkSettings *settings; /* Get the updated palette */ g_free(ui_prefs.color_picker_palette); ui_prefs.color_picker_palette = gtk_color_selection_palette_to_string(colors, n_colors); /* Update the gtk-color-palette setting so all GtkColorSelection widgets will be modified */ settings = gtk_settings_get_for_screen(screen); g_object_set(G_OBJECT(settings), "gtk-color-palette", ui_prefs.color_picker_palette, NULL); } /* This shows the color selection dialog to choose a color. */ void tools_color_chooser(const gchar *color) { GdkColor gc; GtkWidget *colorsel; if (ui_widgets.open_colorsel == NULL) { ui_widgets.open_colorsel = gtk_color_selection_dialog_new(_("Color Chooser")); gtk_dialog_add_button(GTK_DIALOG(ui_widgets.open_colorsel), GTK_STOCK_APPLY, GTK_RESPONSE_APPLY); ui_dialog_set_primary_button_order(GTK_DIALOG(ui_widgets.open_colorsel), GTK_RESPONSE_APPLY, GTK_RESPONSE_CANCEL, GTK_RESPONSE_OK, -1); gtk_widget_set_name(ui_widgets.open_colorsel, "GeanyDialog"); gtk_window_set_transient_for(GTK_WINDOW(ui_widgets.open_colorsel), GTK_WINDOW(main_widgets.window)); colorsel = gtk_color_selection_dialog_get_color_selection(GTK_COLOR_SELECTION_DIALOG(ui_widgets.open_colorsel)); gtk_color_selection_set_has_palette(GTK_COLOR_SELECTION(colorsel), TRUE); gtk_color_selection_set_change_palette_with_screen_hook(on_color_selection_change_palette_with_screen); g_signal_connect(ui_widgets.open_colorsel, "response", G_CALLBACK(on_color_dialog_response), NULL); g_signal_connect(ui_widgets.open_colorsel, "delete-event", G_CALLBACK(gtk_widget_hide_on_delete), NULL); } else colorsel = gtk_color_selection_dialog_get_color_selection(GTK_COLOR_SELECTION_DIALOG(ui_widgets.open_colorsel)); /* if color is non-NULL set it in the dialog as preselected color */ if (color != NULL && utils_parse_color(color, &gc)) { gtk_color_selection_set_current_color(GTK_COLOR_SELECTION(colorsel), &gc); gtk_color_selection_set_previous_color(GTK_COLOR_SELECTION(colorsel), &gc); } /* We make sure the dialog is visible. */ gtk_window_present(GTK_WINDOW(ui_widgets.open_colorsel)); } geany-2.0/src/navqueue.c0000644000175000017500000001546114514252267012202 00000000000000/* * navqueue.c - this file is part of Geany, a fast and lightweight IDE * * Copyright 2007 The Geany contributors * * This program 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; either version 2 of the License, or * (at your option) any later version. * * This program 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /* * Simple code navigation */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include "navqueue.h" #include "document.h" #include "geanyobject.h" #include "sciwrappers.h" #include "toolbar.h" #include "utils.h" #include /* for the navigation history queue */ typedef struct { const gchar *file; /* This is the document's filename, in UTF-8 */ gint pos; } filepos; static GQueue *navigation_queue; static guint nav_queue_pos; static GtkAction *navigation_buttons[2]; void navqueue_init(void) { navigation_queue = g_queue_new(); nav_queue_pos = 0; navigation_buttons[0] = toolbar_get_action_by_name("NavBack"); navigation_buttons[1] = toolbar_get_action_by_name("NavFor"); gtk_action_set_sensitive(navigation_buttons[0], FALSE); gtk_action_set_sensitive(navigation_buttons[1], FALSE); } void navqueue_free(void) { while (! g_queue_is_empty(navigation_queue)) { g_free(g_queue_pop_tail(navigation_queue)); } g_queue_free(navigation_queue); } static void adjust_buttons(void) { if (g_queue_get_length(navigation_queue) < 2) { gtk_action_set_sensitive(navigation_buttons[0], FALSE); gtk_action_set_sensitive(navigation_buttons[1], FALSE); return; } if (nav_queue_pos == 0) { gtk_action_set_sensitive(navigation_buttons[0], TRUE); gtk_action_set_sensitive(navigation_buttons[1], FALSE); return; } /* forward should be sensitive since where not at the start */ gtk_action_set_sensitive(navigation_buttons[1], TRUE); /* back should be sensitive if there's a place to go back to */ (nav_queue_pos < g_queue_get_length(navigation_queue) - 1) ? gtk_action_set_sensitive(navigation_buttons[0], TRUE) : gtk_action_set_sensitive(navigation_buttons[0], FALSE); } static gboolean queue_pos_matches(guint queue_pos, const gchar *fname, gint pos) { if (queue_pos < g_queue_get_length(navigation_queue)) { filepos *fpos = g_queue_peek_nth(navigation_queue, queue_pos); return (utils_str_equal(fpos->file, fname) && fpos->pos == pos); } return FALSE; } static void add_new_position(const gchar *utf8_filename, gint pos) { filepos *npos; guint i; if (queue_pos_matches(nav_queue_pos, utf8_filename, pos)) return; /* prevent duplicates */ npos = g_new0(filepos, 1); npos->file = utf8_filename; npos->pos = pos; /* if we've jumped to a new position from inside the queue rather than going forward */ if (nav_queue_pos > 0) { for (i = 0; i < nav_queue_pos; i++) { g_free(g_queue_pop_head(navigation_queue)); } nav_queue_pos = 0; } g_queue_push_head(navigation_queue, npos); adjust_buttons(); } /** * Adds old file position and new file position to the navqueue, then goes to the new position. * * @param old_doc The document of the previous position, if set as invalid (@c NULL) then no old * position is set * @param new_doc The document of the new position, must be valid. * @param line the line number of the new position. It is counted with 1 as the first line, not 0. * * @return @c TRUE if the cursor has changed the position to @a line or @c FALSE otherwise. **/ GEANY_API_SYMBOL gboolean navqueue_goto_line(GeanyDocument *old_doc, GeanyDocument *new_doc, gint line) { gint pos; g_return_val_if_fail(old_doc == NULL || old_doc->is_valid, FALSE); g_return_val_if_fail(DOC_VALID(new_doc), FALSE); g_return_val_if_fail(line >= 1, FALSE); pos = sci_get_position_from_line(new_doc->editor->sci, line - 1); /* first add old file position */ if (old_doc != NULL && old_doc->file_name) { gint cur_pos = sci_get_current_position(old_doc->editor->sci); add_new_position(old_doc->file_name, cur_pos); } /* now add new file position */ if (new_doc->file_name) { add_new_position(new_doc->file_name, pos); } return editor_goto_pos(new_doc->editor, pos, TRUE); } static gboolean goto_file_pos(const gchar *file, gint pos) { GeanyDocument *doc = document_find_by_filename(file); if (doc == NULL) return FALSE; return editor_goto_pos(doc->editor, pos, TRUE); } void navqueue_go_back(void) { filepos *fprev; GeanyDocument *doc = document_get_current(); /* If the navqueue is currently at some position A, but the actual cursor is at some other * place B, we should add B to the navqueue, so that (1) we go back to A, not to the next * item in the queue; and (2) we can later restore B by going forward. * (If A = B, add_new_position will ignore it.) */ if (doc) { if (doc->file_name) add_new_position(doc->file_name, sci_get_current_position(doc->editor->sci)); } else /* see also https://github.com/geany/geany/pull/1537 */ g_warning("Attempted navigation when nothing is open"); /* return if theres no place to go back to */ if (g_queue_is_empty(navigation_queue) || nav_queue_pos >= g_queue_get_length(navigation_queue) - 1) return; /* jump back */ fprev = g_queue_peek_nth(navigation_queue, nav_queue_pos + 1); if (goto_file_pos(fprev->file, fprev->pos)) { nav_queue_pos++; } else { /** TODO: add option to re open the file */ g_free(g_queue_pop_nth(navigation_queue, nav_queue_pos + 1)); } adjust_buttons(); } void navqueue_go_forward(void) { filepos *fnext; if (nav_queue_pos < 1 || nav_queue_pos >= g_queue_get_length(navigation_queue)) return; /* jump forward */ fnext = g_queue_peek_nth(navigation_queue, nav_queue_pos - 1); if (goto_file_pos(fnext->file, fnext->pos)) { nav_queue_pos--; } else { /** TODO: add option to re open the file */ g_free(g_queue_pop_nth(navigation_queue, nav_queue_pos - 1)); } adjust_buttons(); } static gint find_by_filename(gconstpointer a, gconstpointer b) { if (utils_str_equal(((const filepos*)a)->file, (const gchar*) b)) return 0; else return 1; } /* Remove all elements with the given filename */ void navqueue_remove_file(const gchar *filename) { GList *match; if (filename == NULL) return; while ((match = g_queue_find_custom(navigation_queue, filename, find_by_filename))) { g_free(match->data); g_queue_delete_link(navigation_queue, match); } adjust_buttons(); } geany-2.0/src/tools.h0000644000175000017500000000236014514252267011510 00000000000000/* * tools.h - this file is part of Geany, a fast and lightweight IDE * * Copyright 2006 The Geany contributors * * This program 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; either version 2 of the License, or * (at your option) any later version. * * This program 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef GEANY_TOOLS_H #define GEANY_TOOLS_H 1 #include "document.h" #include G_BEGIN_DECLS void tools_create_insert_custom_command_menu_items(void); void tools_execute_custom_command(GeanyDocument *doc, const gchar *command); void tools_word_count(void); void tools_color_chooser(const gchar *color); G_END_DECLS #endif /* GEANY_TOOLS_H */ geany-2.0/src/templates.h0000644000175000017500000000510414514252267012345 00000000000000/* * templates.h - this file is part of Geany, a fast and lightweight IDE * * Copyright 2005 The Geany contributors * * This program 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; either version 2 of the License, or * (at your option) any later version. * * This program 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /** * @file templates.h * Templates (prefs). **/ #ifndef GEANY_TEMPLATES_H #define GEANY_TEMPLATES_H 1 #include "document.h" #include "filetypes.h" #include G_BEGIN_DECLS /** Template preferences. */ typedef struct GeanyTemplatePrefs { gchar *developer; /**< Name */ gchar *company; /**< Company */ gchar *mail; /**< Email */ gchar *initials; /**< Initials */ gchar *version; /**< Initial version */ gchar *year_format; gchar *date_format; gchar *datetime_format; } GeanyTemplatePrefs; gchar *templates_get_template_fileheader(gint filetype_idx, const gchar *fname); #ifdef GEANY_PRIVATE struct filetype; #define GEANY_TEMPLATES_INDENT 3 #define GEANY_TEMPLATES_FORMAT_YEAR C_("DefaultYear", "%Y") #define GEANY_TEMPLATES_FORMAT_DATE C_("DefaultDate", "%Y-%m-%d") #define GEANY_TEMPLATES_FORMAT_DATETIME C_("DefaultDateTime", "%d.%m.%Y %H:%M:%S %Z") enum { GEANY_TEMPLATE_GPL = 0, GEANY_TEMPLATE_BSD, GEANY_TEMPLATE_FILEHEADER, GEANY_TEMPLATE_CHANGELOG, GEANY_TEMPLATE_FUNCTION, GEANY_MAX_TEMPLATES }; extern GeanyTemplatePrefs template_prefs; void templates_init(void); gchar *templates_get_template_changelog(GeanyDocument *doc); gchar *templates_get_template_function(GeanyDocument *doc, const gchar *func_name); gchar *templates_get_template_licence(GeanyDocument *doc, gint licence_type); void templates_replace_common(GString *tmpl, const gchar *fname, GeanyFiletype *ft, const gchar *func_name); void templates_replace_valist(GString *text, const gchar *first_wildcard, ...) G_GNUC_NULL_TERMINATED; void templates_free_templates(void); #endif /* GEANY_PRIVATE */ G_END_DECLS #endif /* GEANY_TEMPLATES_H */ geany-2.0/src/vte.c0000644000175000017500000007676414514252267011164 00000000000000/* * vte.c - this file is part of Geany, a fast and lightweight IDE * * Copyright 2005 The Geany contributors * * This program 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; either version 2 of the License, or * (at your option) any later version. * * This program 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /* * Virtual Terminal Emulation setup and handling code, using the libvte plugin library. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #ifdef HAVE_VTE #include "vte.h" #include "callbacks.h" #include "document.h" #include "geanyobject.h" #include "msgwindow.h" #include "prefs.h" #include "sciwrappers.h" #include "support.h" #include "ui_utils.h" #include "utils.h" #include "keybindings.h" /* include stdlib.h AND unistd.h, because on GNU/Linux pid_t seems to be * in stdlib.h, on FreeBSD in unistd.h, sys/types.h is needed for C89 */ #include #include #include #include #include #include #include #include VteInfo vte_info = { FALSE, FALSE, FALSE, NULL, NULL }; VteConfig vte_config; static GPid pid = 0; static gboolean clean = TRUE; static GModule *module = NULL; static struct VteFunctions *vf; static gchar *gtk_menu_key_accel = NULL; static GtkWidget *terminal_label = NULL; static guint terminal_label_update_source = 0; /* use vte wordchars to select paths */ static const gchar VTE_WORDCHARS[] = "-A-Za-z0-9,./?%&#:_"; static const gchar VTE_ADDITIONAL_WORDCHARS[] = "-,./?%&#:_"; /* Incomplete VteTerminal struct from vte/vte.h. */ typedef struct _VteTerminal VteTerminal; struct _VteTerminal { GtkWidget widget; GtkAdjustment *adjustment; }; #define VTE_TERMINAL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), VTE_TYPE_TERMINAL, VteTerminal)) #define VTE_TYPE_TERMINAL (vf->vte_terminal_get_type()) typedef enum { VTE_CURSOR_BLINK_SYSTEM, VTE_CURSOR_BLINK_ON, VTE_CURSOR_BLINK_OFF } VteTerminalCursorBlinkMode; typedef enum { /* we don't care for the other possible values */ VTE_PTY_DEFAULT = 0 } VtePtyFlags; /* Holds function pointers we need to access the VTE API. */ struct VteFunctions { guint (*vte_get_major_version) (void); guint (*vte_get_minor_version) (void); GtkWidget* (*vte_terminal_new) (void); pid_t (*vte_terminal_fork_command) (VteTerminal *terminal, const char *command, char **argv, char **envv, const char *directory, gboolean lastlog, gboolean utmp, gboolean wtmp); gboolean (*vte_terminal_spawn_sync) (VteTerminal *terminal, VtePtyFlags pty_flags, const char *working_directory, char **argv, char **envv, GSpawnFlags spawn_flags, GSpawnChildSetupFunc child_setup, gpointer child_setup_data, GPid *child_pid, GCancellable *cancellable, GError **error); void (*vte_terminal_set_size) (VteTerminal *terminal, glong columns, glong rows); void (*vte_terminal_set_word_chars) (VteTerminal *terminal, const char *spec); void (*vte_terminal_set_word_char_exceptions) (VteTerminal *terminal, const char *exceptions); void (*vte_terminal_set_mouse_autohide) (VteTerminal *terminal, gboolean setting); void (*vte_terminal_reset) (VteTerminal *terminal, gboolean full, gboolean clear_history); GType (*vte_terminal_get_type) (void); void (*vte_terminal_set_scroll_on_output) (VteTerminal *terminal, gboolean scroll); void (*vte_terminal_set_scroll_on_keystroke) (VteTerminal *terminal, gboolean scroll); void (*vte_terminal_set_font) (VteTerminal *terminal, const PangoFontDescription *font_desc); void (*vte_terminal_set_scrollback_lines) (VteTerminal *terminal, glong lines); gboolean (*vte_terminal_get_has_selection) (VteTerminal *terminal); void (*vte_terminal_copy_clipboard) (VteTerminal *terminal); void (*vte_terminal_paste_clipboard) (VteTerminal *terminal); void (*vte_terminal_set_color_foreground) (VteTerminal *terminal, const GdkColor *foreground); void (*vte_terminal_set_color_bold) (VteTerminal *terminal, const GdkColor *foreground); void (*vte_terminal_set_color_background) (VteTerminal *terminal, const GdkColor *background); void (*vte_terminal_feed_child) (VteTerminal *terminal, const char *data, glong length); void (*vte_terminal_im_append_menuitems) (VteTerminal *terminal, GtkMenuShell *menushell); void (*vte_terminal_set_cursor_blink_mode) (VteTerminal *terminal, VteTerminalCursorBlinkMode mode); void (*vte_terminal_set_cursor_blinks) (VteTerminal *terminal, gboolean blink); void (*vte_terminal_select_all) (VteTerminal *terminal); void (*vte_terminal_set_audible_bell) (VteTerminal *terminal, gboolean is_audible); GtkAdjustment* (*vte_terminal_get_adjustment) (VteTerminal *terminal); /* hack for the VTE 2.91 API using GdkRGBA: we wrap the API to keep using GdkColor on our side */ void (*vte_terminal_set_color_foreground_rgba) (VteTerminal *terminal, const GdkRGBA *foreground); void (*vte_terminal_set_color_bold_rgba) (VteTerminal *terminal, const GdkRGBA *foreground); void (*vte_terminal_set_color_background_rgba) (VteTerminal *terminal, const GdkRGBA *background); }; static void create_vte(void); static void vte_start(GtkWidget *widget); static void vte_restart(GtkWidget *widget); static gboolean vte_button_pressed(GtkWidget *widget, GdkEventButton *event, gpointer user_data); static gboolean vte_keyrelease_cb(GtkWidget *widget, GdkEventKey *event, gpointer data); static gboolean vte_keypress_cb(GtkWidget *widget, GdkEventKey *event, gpointer data); static gboolean vte_register_symbols(GModule *module); static void vte_popup_menu_clicked(GtkMenuItem *menuitem, gpointer user_data); static GtkWidget *vte_create_popup_menu(void); static void vte_commit_cb(VteTerminal *vte, gchar *arg1, guint arg2, gpointer user_data); static void vte_drag_data_received(GtkWidget *widget, GdkDragContext *drag_context, gint x, gint y, GtkSelectionData *data, guint info, guint ltime); enum { POPUP_COPY, POPUP_PASTE, POPUP_SELECTALL, POPUP_CHANGEPATH, POPUP_RESTARTTERMINAL, POPUP_PREFERENCES, TARGET_UTF8_STRING = 0, TARGET_TEXT, TARGET_COMPOUND_TEXT, TARGET_STRING, TARGET_TEXT_PLAIN }; static const GtkTargetEntry dnd_targets[] = { { "UTF8_STRING", 0, TARGET_UTF8_STRING }, { "TEXT", 0, TARGET_TEXT }, { "COMPOUND_TEXT", 0, TARGET_COMPOUND_TEXT }, { "STRING", 0, TARGET_STRING }, { "text/plain", 0, TARGET_TEXT_PLAIN }, }; /* replacement for vte_terminal_get_adjustment() when it's not available */ static GtkAdjustment *default_vte_terminal_get_adjustment(VteTerminal *vte) { if (GTK_IS_SCROLLABLE(vte)) return gtk_scrollable_get_vadjustment(GTK_SCROLLABLE(vte)); /* this is only valid in < 0.38, 0.38 broke ABI */ return vte->adjustment; } /* Wrap VTE 2.91 API using GdkRGBA with GdkColor so we use a single API on our side */ static void rgba_from_color(GdkRGBA *rgba, const GdkColor *color) { rgba->red = color->red / 65535.0; rgba->green = color->green / 65535.0; rgba->blue = color->blue / 65535.0; rgba->alpha = 1.0; } #define WRAP_RGBA_SETTER(name) \ static void wrap_##name(VteTerminal *terminal, const GdkColor *color) \ { \ GdkRGBA rgba; \ rgba_from_color(&rgba, color); \ vf->name##_rgba(terminal, &rgba); \ } WRAP_RGBA_SETTER(vte_terminal_set_color_background) WRAP_RGBA_SETTER(vte_terminal_set_color_bold) WRAP_RGBA_SETTER(vte_terminal_set_color_foreground) #undef WRAP_RGBA_SETTER static gchar **vte_get_child_environment(void) { const gchar *exclude_vars[] = {"COLUMNS", "LINES", "TERM", "TERM_PROGRAM", NULL}; return utils_copy_environment(exclude_vars, "TERM", "xterm", NULL); } static void override_menu_key(void) { if (gtk_menu_key_accel == NULL) /* for restoring the default value */ g_object_get(G_OBJECT(gtk_settings_get_default()), "gtk-menu-bar-accel", >k_menu_key_accel, NULL); if (vte_config.ignore_menu_bar_accel) gtk_settings_set_string_property(gtk_settings_get_default(), "gtk-menu-bar-accel", "F10", "Geany"); else gtk_settings_set_string_property(gtk_settings_get_default(), "gtk-menu-bar-accel", gtk_menu_key_accel, "Geany"); } static void on_startup_complete(G_GNUC_UNUSED GObject *dummy) { GeanyDocument *doc = document_get_current(); /* ensure the widget is mapped and fully initialized, so actions like pasting text work * (see https://github.com/geany/geany/issues/2813 for details) */ gtk_widget_realize(vte_config.vte); if (doc) vte_cwd((doc->real_path != NULL) ? doc->real_path : doc->file_name, FALSE); } void vte_init(void) { if (vte_info.have_vte == FALSE) { /* vte_info.have_vte can be false even if VTE is compiled in, think of command line option */ geany_debug("Disabling terminal support"); return; } if (!EMPTY(vte_info.lib_vte)) { module = g_module_open(vte_info.lib_vte, G_MODULE_BIND_LAZY); } #ifdef VTE_MODULE_PATH else { module = g_module_open(VTE_MODULE_PATH, G_MODULE_BIND_LAZY); } #endif if (module == NULL) { gint i; const gchar *sonames[] = { #ifdef __APPLE__ "libvte-2.91.0.dylib", "libvte-2.91.dylib", "libvte2_90.9.dylib", "libvte2_90.dylib", #endif "libvte-2.91.so", "libvte-2.91.so.0", "libvte2_90.so", "libvte2_90.so.9", NULL }; for (i = 0; sonames[i] != NULL && module == NULL; i++) { module = g_module_open(sonames[i], G_MODULE_BIND_LAZY); } } if (module == NULL) { vte_info.have_vte = FALSE; geany_debug("Could not load libvte.so, embedded terminal support disabled"); return; } else { geany_debug("Loaded libvte from %s", g_module_name(module)); vf = g_new0(struct VteFunctions, 1); if (vte_register_symbols(module)) vte_info.have_vte = TRUE; else { vte_info.have_vte = FALSE; g_free(vf); /* FIXME: is closing the module safe? see vte_close() and test on FreeBSD */ /*g_module_close(module);*/ module = NULL; return; } } create_vte(); /* setup the F10 menu override (so it works before the widget is first realised). */ override_menu_key(); g_signal_connect(geany_object, "geany-startup-complete", G_CALLBACK(on_startup_complete), NULL); } static void on_vte_realize(void) { /* the vte widget has to be realised before color changes take effect */ vte_apply_user_settings(); if (vf->vte_terminal_im_append_menuitems && vte_config.im_submenu) vf->vte_terminal_im_append_menuitems(VTE_TERMINAL(vte_config.vte), GTK_MENU_SHELL(vte_config.im_submenu)); } static gboolean vte_start_idle(G_GNUC_UNUSED gpointer user_data) { vte_start(vte_config.vte); return FALSE; } static void create_vte(void) { GtkWidget *vte, *scrollbar, *hbox; vte_config.vte = vte = vf->vte_terminal_new(); scrollbar = gtk_scrollbar_new(GTK_ORIENTATION_VERTICAL, vf->vte_terminal_get_adjustment(VTE_TERMINAL(vte))); gtk_widget_set_can_focus(scrollbar, FALSE); /* create menu now so copy/paste shortcuts work */ vte_config.menu = vte_create_popup_menu(); g_object_ref_sink(vte_config.menu); hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); gtk_box_pack_start(GTK_BOX(hbox), vte, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(hbox), scrollbar, FALSE, FALSE, 0); /* set the default widget size first to prevent VTE expanding too much, * sometimes causing the hscrollbar to be too big or out of view. */ gtk_widget_set_size_request(GTK_WIDGET(vte), 10, 10); vf->vte_terminal_set_size(VTE_TERMINAL(vte), 30, 1); vf->vte_terminal_set_mouse_autohide(VTE_TERMINAL(vte), TRUE); if (vf->vte_terminal_set_word_chars) vf->vte_terminal_set_word_chars(VTE_TERMINAL(vte), VTE_WORDCHARS); else if (vf->vte_terminal_set_word_char_exceptions) vf->vte_terminal_set_word_char_exceptions(VTE_TERMINAL(vte), VTE_ADDITIONAL_WORDCHARS); gtk_drag_dest_set(vte, GTK_DEST_DEFAULT_ALL, dnd_targets, G_N_ELEMENTS(dnd_targets), GDK_ACTION_COPY); g_signal_connect(vte, "child-exited", G_CALLBACK(vte_start), NULL); g_signal_connect(vte, "button-press-event", G_CALLBACK(vte_button_pressed), NULL); g_signal_connect(vte, "event", G_CALLBACK(vte_keypress_cb), NULL); g_signal_connect(vte, "key-release-event", G_CALLBACK(vte_keyrelease_cb), NULL); g_signal_connect(vte, "commit", G_CALLBACK(vte_commit_cb), NULL); g_signal_connect(vte, "motion-notify-event", G_CALLBACK(on_motion_event), NULL); g_signal_connect(vte, "drag-data-received", G_CALLBACK(vte_drag_data_received), NULL); /* start shell on idle otherwise the initial prompt can get corrupted */ g_idle_add(vte_start_idle, NULL); gtk_widget_show_all(hbox); terminal_label = gtk_label_new(_("Terminal")); gtk_notebook_insert_page(GTK_NOTEBOOK(msgwindow.notebook), hbox, terminal_label, MSG_VTE); g_signal_connect_after(vte, "realize", G_CALLBACK(on_vte_realize), NULL); } void vte_close(void) { /* free the vte widget before unloading vte module * this prevents a segfault on X close window if the message window is hidden */ g_signal_handlers_disconnect_by_func(vte_config.vte, G_CALLBACK(vte_start), NULL); gtk_widget_destroy(vte_config.vte); gtk_widget_destroy(vte_config.menu); g_object_unref(vte_config.menu); g_free(vte_config.shell); g_free(vte_config.font); g_free(vte_config.send_cmd_prefix); g_free(vf); g_free(gtk_menu_key_accel); /* Don't unload the module explicitly because it causes a segfault on FreeBSD. The segfault * happens when the app really exits, not directly on g_module_close(). This still needs to * be investigated. */ /*g_module_close(module); */ } static gboolean set_dirty_idle(gpointer user_data) { gtk_widget_set_name(terminal_label, "geany-terminal-dirty"); terminal_label_update_source = 0; return FALSE; } static void set_clean(gboolean value) { if (clean != value) { if (terminal_label) { if (terminal_label_update_source > 0) { g_source_remove(terminal_label_update_source); terminal_label_update_source = 0; } if (value) gtk_widget_set_name(terminal_label, NULL); else terminal_label_update_source = g_timeout_add(150, set_dirty_idle, NULL); } clean = value; } } static gboolean vte_keyrelease_cb(GtkWidget *widget, GdkEventKey *event, gpointer data) { if (ui_is_keyval_enter_or_return(event->keyval) || ((event->keyval == GDK_KEY_c) && (event->state & GDK_CONTROL_MASK))) { /* assume any text on the prompt has been executed when pressing Enter/Return */ set_clean(TRUE); } return FALSE; } static gboolean vte_keypress_cb(GtkWidget *widget, GdkEventKey *event, gpointer data) { if (vte_config.enable_bash_keys) return FALSE; /* Ctrl-[CD] will be handled by the VTE itself */ if (event->type != GDK_KEY_RELEASE) return FALSE; if ((event->keyval == GDK_KEY_c || event->keyval == GDK_KEY_d || event->keyval == GDK_KEY_C || event->keyval == GDK_KEY_D) && event->state & GDK_CONTROL_MASK && ! (event->state & GDK_SHIFT_MASK) && ! (event->state & GDK_MOD1_MASK)) { vte_restart(widget); return TRUE; } return FALSE; } static void vte_commit_cb(VteTerminal *vte, gchar *arg1, guint arg2, gpointer user_data) { set_clean(FALSE); } static void vte_start(GtkWidget *widget) { /* split the shell command line, so arguments will work too */ gchar **argv = g_strsplit(vte_config.shell, " ", -1); if (argv != NULL) { gchar **env = vte_get_child_environment(); if (vf->vte_terminal_spawn_sync) { if (! vf->vte_terminal_spawn_sync(VTE_TERMINAL(widget), VTE_PTY_DEFAULT, vte_info.dir, argv, env, 0, NULL, NULL, &pid, NULL, NULL)) { pid = -1; } } else { pid = vf->vte_terminal_fork_command(VTE_TERMINAL(widget), argv[0], argv, env, vte_info.dir, TRUE, TRUE, TRUE); } g_strfreev(env); g_strfreev(argv); } else pid = 0; /* use 0 as invalid pid */ set_clean(TRUE); } static void vte_restart(GtkWidget *widget) { vte_get_working_directory(); /* try to keep the working directory when restarting the VTE */ if (pid > 0) { kill(pid, SIGINT); pid = 0; } vf->vte_terminal_reset(VTE_TERMINAL(widget), TRUE, TRUE); vte_start(widget); set_clean(TRUE); } static gboolean vte_button_pressed(GtkWidget *widget, GdkEventButton *event, gpointer user_data) { if (event->button == 3) { gtk_widget_grab_focus(vte_config.vte); gtk_menu_popup_at_pointer(GTK_MENU(vte_config.menu), (GdkEvent *) event); return TRUE; } else if (event->button == 2) { gtk_widget_grab_focus(widget); } return FALSE; } static void vte_set_cursor_blink_mode(void) { if (vf->vte_terminal_set_cursor_blink_mode != NULL) /* vte >= 0.17.1 */ vf->vte_terminal_set_cursor_blink_mode(VTE_TERMINAL(vte_config.vte), (vte_config.cursor_blinks) ? VTE_CURSOR_BLINK_ON : VTE_CURSOR_BLINK_OFF); else /* vte < 0.17.1 */ vf->vte_terminal_set_cursor_blinks(VTE_TERMINAL(vte_config.vte), vte_config.cursor_blinks); } static gboolean vte_is_2_91(void) { guint major = vf->vte_get_major_version ? vf->vte_get_major_version() : 0; guint minor = vf->vte_get_minor_version ? vf->vte_get_minor_version() : 0; /* 2.91 API started at 0.38 */ return ((major > 0 || (major == 0 && minor >= 38)) || /* 0.38 doesn't have runtime version checks, so check a symbol that didn't exist before */ vf->vte_terminal_spawn_sync != NULL); } static gboolean vte_register_symbols(GModule *mod) { #define BIND_SYMBOL_FULL(name, dest) \ g_module_symbol(mod, name, (void*)(dest)) #define BIND_SYMBOL(field) \ BIND_SYMBOL_FULL(#field, &vf->field) #define BIND_REQUIRED_SYMBOL_FULL(name, dest) \ G_STMT_START { \ if (! BIND_SYMBOL_FULL(name, dest)) \ { \ g_critical(_("invalid VTE library \"%s\": missing symbol \"%s\""), \ g_module_name(mod), name); \ return FALSE; \ } \ } G_STMT_END #define BIND_REQUIRED_SYMBOL(field) \ BIND_REQUIRED_SYMBOL_FULL(#field, &vf->field) #define BIND_REQUIRED_SYMBOL_RGBA_WRAPPED(field) \ G_STMT_START { \ BIND_REQUIRED_SYMBOL_FULL(#field, &vf->field##_rgba); \ vf->field = wrap_##field; \ } G_STMT_END BIND_SYMBOL(vte_get_major_version); BIND_SYMBOL(vte_get_minor_version); BIND_REQUIRED_SYMBOL(vte_terminal_new); BIND_REQUIRED_SYMBOL(vte_terminal_set_size); if (! BIND_SYMBOL(vte_terminal_spawn_sync)) /* vte_terminal_spawn_sync() is available only in 0.38 */ BIND_REQUIRED_SYMBOL(vte_terminal_fork_command); /* 0.38 removed vte_terminal_set_word_chars() */ BIND_SYMBOL(vte_terminal_set_word_chars); /* 0.40 introduced it under a different API */ BIND_SYMBOL(vte_terminal_set_word_char_exceptions); BIND_REQUIRED_SYMBOL(vte_terminal_set_mouse_autohide); BIND_REQUIRED_SYMBOL(vte_terminal_reset); BIND_REQUIRED_SYMBOL(vte_terminal_get_type); BIND_REQUIRED_SYMBOL(vte_terminal_set_scroll_on_output); BIND_REQUIRED_SYMBOL(vte_terminal_set_scroll_on_keystroke); BIND_REQUIRED_SYMBOL(vte_terminal_set_font); BIND_REQUIRED_SYMBOL(vte_terminal_set_scrollback_lines); BIND_REQUIRED_SYMBOL(vte_terminal_get_has_selection); BIND_REQUIRED_SYMBOL(vte_terminal_copy_clipboard); BIND_REQUIRED_SYMBOL(vte_terminal_paste_clipboard); if (vte_is_2_91()) { BIND_REQUIRED_SYMBOL_RGBA_WRAPPED(vte_terminal_set_color_foreground); BIND_REQUIRED_SYMBOL_RGBA_WRAPPED(vte_terminal_set_color_bold); BIND_REQUIRED_SYMBOL_RGBA_WRAPPED(vte_terminal_set_color_background); } else { BIND_REQUIRED_SYMBOL(vte_terminal_set_color_foreground); BIND_REQUIRED_SYMBOL(vte_terminal_set_color_bold); BIND_REQUIRED_SYMBOL(vte_terminal_set_color_background); } BIND_REQUIRED_SYMBOL(vte_terminal_feed_child); BIND_SYMBOL(vte_terminal_im_append_menuitems); if (! BIND_SYMBOL(vte_terminal_set_cursor_blink_mode)) /* vte_terminal_set_cursor_blink_mode() is only available since 0.17.1, so if we don't find * this symbol, we are probably on an older version and use the old API instead */ BIND_REQUIRED_SYMBOL(vte_terminal_set_cursor_blinks); BIND_REQUIRED_SYMBOL(vte_terminal_select_all); BIND_REQUIRED_SYMBOL(vte_terminal_set_audible_bell); if (! BIND_SYMBOL(vte_terminal_get_adjustment)) /* vte_terminal_get_adjustment() is available since 0.9 and removed in 0.38 */ vf->vte_terminal_get_adjustment = default_vte_terminal_get_adjustment; #undef BIND_REQUIRED_SYMBOL_RGBA_WRAPPED #undef BIND_REQUIRED_SYMBOL #undef BIND_REQUIRED_SYMBOL_FULL #undef BIND_SYMBOL #undef BIND_SYMBOL_FULL return TRUE; } void vte_apply_user_settings(void) { VteConfig *vc = &vte_config; PangoFontDescription *font_desc; if (! ui_prefs.msgwindow_visible) return; vf->vte_terminal_set_scrollback_lines(VTE_TERMINAL(vc->vte), vc->scrollback_lines); vf->vte_terminal_set_scroll_on_keystroke(VTE_TERMINAL(vc->vte), vc->scroll_on_key); vf->vte_terminal_set_scroll_on_output(VTE_TERMINAL(vc->vte), vc->scroll_on_out); font_desc = pango_font_description_from_string(vc->font); vf->vte_terminal_set_font(VTE_TERMINAL(vc->vte), font_desc); pango_font_description_free(font_desc); vf->vte_terminal_set_color_foreground(VTE_TERMINAL(vc->vte), &vc->colour_fore); vf->vte_terminal_set_color_bold(VTE_TERMINAL(vc->vte), &vc->colour_fore); vf->vte_terminal_set_color_background(VTE_TERMINAL(vc->vte), &vc->colour_back); vf->vte_terminal_set_audible_bell(VTE_TERMINAL(vc->vte), prefs.beep_on_errors); vte_set_cursor_blink_mode(); override_menu_key(); } static void vte_popup_menu_clicked(GtkMenuItem *menuitem, gpointer user_data) { switch (GPOINTER_TO_INT(user_data)) { case POPUP_COPY: { if (vf->vte_terminal_get_has_selection(VTE_TERMINAL(vte_config.vte))) vf->vte_terminal_copy_clipboard(VTE_TERMINAL(vte_config.vte)); break; } case POPUP_PASTE: { vf->vte_terminal_paste_clipboard(VTE_TERMINAL(vte_config.vte)); break; } case POPUP_SELECTALL: { vte_select_all(); break; } case POPUP_CHANGEPATH: { GeanyDocument *doc = document_get_current(); if (doc != NULL) vte_cwd(doc->file_name, TRUE); break; } case POPUP_RESTARTTERMINAL: { vte_restart(vte_config.vte); break; } case POPUP_PREFERENCES: { GtkWidget *notebook, *tab_page; prefs_show_dialog(); notebook = ui_lookup_widget(ui_widgets.prefs_dialog, "notebook2"); tab_page = ui_lookup_widget(ui_widgets.prefs_dialog, "frame_term"); gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook), gtk_notebook_page_num(GTK_NOTEBOOK(notebook), GTK_WIDGET(tab_page))); break; } } } static GtkWidget *vte_create_popup_menu(void) { GtkWidget *menu, *item; GtkAccelGroup *accel_group; menu = gtk_menu_new(); accel_group = gtk_accel_group_new(); gtk_window_add_accel_group(GTK_WINDOW(main_widgets.window), accel_group); item = gtk_image_menu_item_new_from_stock(GTK_STOCK_COPY, NULL); gtk_widget_add_accelerator(item, "activate", accel_group, GDK_KEY_c, GEANY_PRIMARY_MOD_MASK | GDK_SHIFT_MASK, GTK_ACCEL_VISIBLE); gtk_widget_show(item); gtk_container_add(GTK_CONTAINER(menu), item); g_signal_connect(item, "activate", G_CALLBACK(vte_popup_menu_clicked), GINT_TO_POINTER(POPUP_COPY)); item = gtk_image_menu_item_new_from_stock(GTK_STOCK_PASTE, NULL); gtk_widget_add_accelerator(item, "activate", accel_group, GDK_KEY_v, GEANY_PRIMARY_MOD_MASK | GDK_SHIFT_MASK, GTK_ACCEL_VISIBLE); gtk_widget_show(item); gtk_container_add(GTK_CONTAINER(menu), item); g_signal_connect(item, "activate", G_CALLBACK(vte_popup_menu_clicked), GINT_TO_POINTER(POPUP_PASTE)); item = gtk_separator_menu_item_new(); gtk_widget_show(item); gtk_container_add(GTK_CONTAINER(menu), item); item = gtk_image_menu_item_new_from_stock(GTK_STOCK_SELECT_ALL, NULL); gtk_widget_show(item); gtk_container_add(GTK_CONTAINER(menu), item); g_signal_connect(item, "activate", G_CALLBACK(vte_popup_menu_clicked), GINT_TO_POINTER(POPUP_SELECTALL)); item = gtk_separator_menu_item_new(); gtk_widget_show(item); gtk_container_add(GTK_CONTAINER(menu), item); item = gtk_image_menu_item_new_with_mnemonic(_("_Set Path From Document")); gtk_widget_show(item); gtk_container_add(GTK_CONTAINER(menu), item); g_signal_connect(item, "activate", G_CALLBACK(vte_popup_menu_clicked), GINT_TO_POINTER(POPUP_CHANGEPATH)); item = gtk_image_menu_item_new_with_mnemonic(_("_Restart Terminal")); gtk_widget_show(item); gtk_container_add(GTK_CONTAINER(menu), item); g_signal_connect(item, "activate", G_CALLBACK(vte_popup_menu_clicked), GINT_TO_POINTER(POPUP_RESTARTTERMINAL)); item = gtk_separator_menu_item_new(); gtk_widget_show(item); gtk_container_add(GTK_CONTAINER(menu), item); item = gtk_image_menu_item_new_from_stock(GTK_STOCK_PREFERENCES, NULL); gtk_widget_show(item); gtk_container_add(GTK_CONTAINER(menu), item); g_signal_connect(item, "activate", G_CALLBACK(vte_popup_menu_clicked), GINT_TO_POINTER(POPUP_PREFERENCES)); msgwin_menu_add_common_items(GTK_MENU(menu)); vte_config.im_submenu = NULL; return menu; } /* If the command could be executed, TRUE is returned, FALSE otherwise (i.e. there was some text * on the prompt). */ gboolean vte_send_cmd(const gchar *cmd) { g_return_val_if_fail(cmd != NULL, FALSE); if (clean) { vf->vte_terminal_feed_child(VTE_TERMINAL(vte_config.vte), cmd, strlen(cmd)); set_clean(TRUE); /* vte_terminal_feed_child() also marks the vte as not clean */ return TRUE; } else return FALSE; } /* Taken from Terminal by os-cillation: terminal_screen_get_working_directory, thanks. * Determines the working directory using various OS-specific mechanisms and stores the determined * directory in vte_info.dir. Note: vte_info.dir contains the real path. */ const gchar *vte_get_working_directory(void) { if (pid > 0) { gchar buffer[4096 + 1]; gchar *file = g_strdup_printf("/proc/%d/cwd", pid); gint length = readlink(file, buffer, sizeof(buffer)); if (length > 0 && *buffer == '/') { buffer[length] = '\0'; g_free(vte_info.dir); vte_info.dir = g_strdup(buffer); } else if (length == 0) { gchar *cwd = g_get_current_dir(); if (cwd != NULL) { if (chdir(file) == 0) { g_free(vte_info.dir); vte_info.dir = g_get_current_dir(); if (chdir(cwd) != 0) geany_debug("%s: %s", G_STRFUNC, g_strerror(errno)); } g_free(cwd); } } g_free(file); } return vte_info.dir; } /* Changes the current working directory of the VTE to the path of the given filename. * filename is expected to be in UTF-8 encoding. * filename can also be a path, then it is used directly. * If force is set to TRUE, it will always change the cwd */ void vte_cwd(const gchar *filename, gboolean force) { if (vte_info.have_vte && (vte_config.follow_path || force) && filename != NULL && g_path_is_absolute(filename)) { gchar *path; if (g_file_test(filename, G_FILE_TEST_IS_DIR)) path = g_strdup(filename); else path = g_path_get_dirname(filename); vte_get_working_directory(); /* refresh vte_info.dir */ if (! utils_str_equal(path, vte_info.dir)) { /* use g_shell_quote to avoid problems with spaces, '!' or something else in path */ gchar *quoted_path = g_shell_quote(path); const gchar *cmd_prefix = vte_config.send_cmd_prefix ? vte_config.send_cmd_prefix : ""; gchar *cmd = g_strconcat(cmd_prefix, "cd ", quoted_path, "\n", NULL); if (! vte_send_cmd(cmd)) { const gchar *msg = _("Directory not changed because the terminal may contain some input (press Ctrl+C or Enter to clear it)."); ui_set_statusbar(FALSE, "%s", msg); geany_debug("%s", msg); } g_free(quoted_path); g_free(cmd); } g_free(path); } } static void vte_drag_data_received(GtkWidget *widget, GdkDragContext *drag_context, gint x, gint y, GtkSelectionData *data, guint info, guint ltime) { if (info == TARGET_TEXT_PLAIN) { if (gtk_selection_data_get_format(data) == 8 && gtk_selection_data_get_length(data) > 0) vf->vte_terminal_feed_child(VTE_TERMINAL(widget), (const gchar*) gtk_selection_data_get_data(data), gtk_selection_data_get_length(data)); } else { gchar *text = (gchar*) gtk_selection_data_get_text(data); if (!EMPTY(text)) vf->vte_terminal_feed_child(VTE_TERMINAL(widget), text, strlen(text)); g_free(text); } gtk_drag_finish(drag_context, TRUE, FALSE, ltime); } static void on_check_run_in_vte_toggled(GtkToggleButton *togglebutton, GtkWidget *user_data) { g_return_if_fail(GTK_IS_WIDGET(user_data)); gtk_widget_set_sensitive(user_data, gtk_toggle_button_get_active(togglebutton)); } static void on_term_font_set(GtkFontButton *widget, gpointer user_data) { const gchar *fontbtn = gtk_font_button_get_font_name(widget); if (! utils_str_equal(fontbtn, vte_config.font)) { SETPTR(vte_config.font, g_strdup(gtk_font_button_get_font_name(widget))); vte_apply_user_settings(); } } static void on_term_fg_color_set(GtkColorButton *widget, gpointer user_data) { gtk_color_button_get_color(widget, &vte_config.colour_fore); } static void on_term_bg_color_set(GtkColorButton *widget, gpointer user_data) { gtk_color_button_get_color(widget, &vte_config.colour_back); } void vte_append_preferences_tab(void) { if (vte_info.have_vte) { GtkWidget *frame_term, *button_shell, *entry_shell; GtkWidget *check_run_in_vte, *check_skip_script; GtkWidget *font_button, *fg_color_button, *bg_color_button; button_shell = GTK_WIDGET(ui_lookup_widget(ui_widgets.prefs_dialog, "button_term_shell")); entry_shell = GTK_WIDGET(ui_lookup_widget(ui_widgets.prefs_dialog, "entry_shell")); ui_setup_open_button_callback(button_shell, NULL, GTK_FILE_CHOOSER_ACTION_OPEN, GTK_ENTRY(entry_shell)); check_skip_script = GTK_WIDGET(ui_lookup_widget(ui_widgets.prefs_dialog, "check_skip_script")); gtk_widget_set_sensitive(check_skip_script, vte_config.run_in_vte); check_run_in_vte = GTK_WIDGET(ui_lookup_widget(ui_widgets.prefs_dialog, "check_run_in_vte")); g_signal_connect(G_OBJECT(check_run_in_vte), "toggled", G_CALLBACK(on_check_run_in_vte_toggled), check_skip_script); font_button = ui_lookup_widget(ui_widgets.prefs_dialog, "font_term"); g_signal_connect(font_button, "font-set", G_CALLBACK(on_term_font_set), NULL); fg_color_button = ui_lookup_widget(ui_widgets.prefs_dialog, "color_fore"); g_signal_connect(fg_color_button, "color-set", G_CALLBACK(on_term_fg_color_set), NULL); bg_color_button = ui_lookup_widget(ui_widgets.prefs_dialog, "color_back"); g_signal_connect(bg_color_button, "color-set", G_CALLBACK(on_term_bg_color_set), NULL); frame_term = ui_lookup_widget(ui_widgets.prefs_dialog, "frame_term"); gtk_widget_show_all(frame_term); } } void vte_select_all(void) { if (vf->vte_terminal_select_all != NULL) vf->vte_terminal_select_all(VTE_TERMINAL(vte_config.vte)); } void vte_send_selection_to_vte(void) { GeanyDocument *doc; gchar *text; gsize len; doc = document_get_current(); g_return_if_fail(doc != NULL); if (sci_has_selection(doc->editor->sci)) { text = sci_get_selection_contents(doc->editor->sci); } else { /* Get the current line */ gint line_num = sci_get_current_line(doc->editor->sci); text = sci_get_line(doc->editor->sci, line_num); } len = strlen(text); if (vte_config.send_selection_unsafe) { /* Explicitly append a trailing newline character to get the command executed, this is disabled by default as it could cause all sorts of damage. */ if (text[len-1] != '\n' && text[len-1] != '\r') { SETPTR(text, g_strconcat(text, "\n", NULL)); len++; } } else { /* Make sure there is no newline character at the end to prevent unwanted execution */ while (text[len-1] == '\n' || text[len-1] == '\r') { text[len-1] = '\0'; len--; } } vf->vte_terminal_feed_child(VTE_TERMINAL(vte_config.vte), text, len); /* show the VTE */ gtk_notebook_set_current_page(GTK_NOTEBOOK(msgwindow.notebook), MSG_VTE); gtk_widget_grab_focus(vte_config.vte); msgwin_show_hide(TRUE); g_free(text); } #endif geany-2.0/src/keybindings.c0000644000175000017500000025331714514252267012663 00000000000000/* * keybindings.c - this file is part of Geany, a fast and lightweight IDE * * Copyright 2006 The Geany contributors * * This program 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; either version 2 of the License, or * (at your option) any later version. * * This program 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /** * @file keybindings.h * Configurable keyboard shortcuts. * - keybindings_send_command() mimics a built-in keybinding action. * - @ref GeanyKeyGroupID lists groups of built-in keybindings. * @see plugin_set_key_group(). **/ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include "keybindings.h" #include "app.h" #include "build.h" #include "callbacks.h" #include "documentprivate.h" #include "filetypes.h" #include "geanyobject.h" #include "keybindingsprivate.h" #include "main.h" #include "msgwindow.h" #include "navqueue.h" #include "notebook.h" #include "prefs.h" #include "sciwrappers.h" #include "sidebar.h" #include "support.h" #include "symbols.h" #include "toolbar.h" #include "tools.h" #include "ui_utils.h" #include "utils.h" #include "vte.h" #include #include #include GPtrArray *keybinding_groups; /* array of GeanyKeyGroup pointers, in visual order */ /* keyfile group name for non-plugin KB groups */ static const gchar keybindings_keyfile_group_name[] = "Bindings"; /* core keybindings */ static GeanyKeyBinding binding_ids[GEANY_KEYS_COUNT]; static GtkAccelGroup *kb_accel_group = NULL; static const gboolean swap_alt_tab_order = FALSE; /* central keypress event handler, almost all keypress events go to this function */ static gboolean on_key_press_event(GtkWidget *widget, GdkEventKey *event, gpointer user_data); static gboolean check_current_word(GeanyDocument *doc, gboolean sci_word); static gboolean read_current_word(GeanyDocument *doc, gboolean sci_word); static gchar *get_current_word_or_sel(GeanyDocument *doc, gboolean sci_word); static gboolean cb_func_file_action(guint key_id); static gboolean cb_func_project_action(guint key_id); static gboolean cb_func_editor_action(guint key_id); static gboolean cb_func_select_action(guint key_id); static gboolean cb_func_format_action(guint key_id); static gboolean cb_func_insert_action(guint key_id); static gboolean cb_func_search_action(guint key_id); static gboolean cb_func_goto_action(guint key_id); static gboolean cb_func_switch_action(guint key_id); static gboolean cb_func_clipboard_action(guint key_id); static gboolean cb_func_document_action(guint key_id); static gboolean cb_func_view_action(guint key_id); /* note: new keybindings should normally use per group callbacks */ static void cb_func_menu_help(guint key_id); static void cb_func_menu_preferences(guint key_id); static void cb_func_menu_fullscreen(guint key_id); static void cb_func_menu_messagewindow(guint key_id); static void cb_func_menu_opencolorchooser(guint key_id); static void cb_func_switch_tableft(guint key_id); static void cb_func_switch_tabright(guint key_id); static void cb_func_switch_tablastused(guint key_id); static void cb_func_move_tab(guint key_id); static void add_popup_menu_accels(void); /** Gets significant modifiers from a GdkModifierType mask. The set of * significant modifiers corresponds to the default modifier mask as returned * by @c gtk_accelerator_get_default_mod_mask(). In addition, it improves * the Command key handling on OS X by adding @c GEANY_PRIMARY_MOD_MASK * when needed. For this reason it is preferred to use this function * instead of @c gtk_accelerator_set_default_mod_mask(). * @param mods GdkModifierType mask. * @return Significant modifiers from the mask. * @since 1.25. */ GEANY_API_SYMBOL GdkModifierType keybindings_get_modifiers(GdkModifierType mods) { #ifdef __APPLE__ if (mods & GDK_MOD2_MASK) { mods |= GEANY_PRIMARY_MOD_MASK; mods &= ~GDK_MOD2_MASK; } #endif return mods & gtk_accelerator_get_default_mod_mask(); } /** Looks up a keybinding item. * @param group Group. * @param key_id Keybinding index for the group. * @return @transfer{none} The keybinding. * @since 0.19. */ GEANY_API_SYMBOL GeanyKeyBinding *keybindings_get_item(GeanyKeyGroup *group, gsize key_id) { if (group->plugin) { g_assert(key_id < group->plugin_key_count); return &group->plugin_keys[key_id]; } g_assert(key_id < GEANY_KEYS_COUNT); return &binding_ids[key_id]; } /* This is used to set default keybindings on startup. * Menu accels are set in apply_kb_accel(). */ /** @girskip * Fills a GeanyKeyBinding struct item. * @note Always set @a key and @a mod to 0, otherwise you will likely * cause conflicts with the user's custom, other plugin's keybindings or * future default keybindings. * @param group Group. * @param key_id Keybinding index for the group. * @param callback @nullable Function to call when activated, or @c NULL to use the group callback. * Usually it's better to use the group callback instead - see plugin_set_key_group(). * @param key Default key, e.g. @c GDK_KEY_j (must be lower case), but usually 0 for unset. * @param mod Default modifier, e.g. @c GDK_CONTROL_MASK, but usually 0 for unset. * @param kf_name Key name used for this item in the keybindings configuration file, i.e. @c "menu_new". * @param label Label used in the preferences dialog keybindings tab. May contain * underscores - these won't be displayed. * @param menu_item @nullable Optional widget to set an accelerator for, or @c NULL. * @return The keybinding - normally this is ignored. */ GEANY_API_SYMBOL GeanyKeyBinding *keybindings_set_item(GeanyKeyGroup *group, gsize key_id, GeanyKeyCallback callback, guint key, GdkModifierType mod, const gchar *kf_name, const gchar *label, GtkWidget *menu_item) { GeanyKeyBinding *kb; g_assert(group->name); kb = keybindings_get_item(group, key_id); g_assert(!kb->name); g_ptr_array_add(group->key_items, kb); if (group->plugin) { /* some plugins e.g. GeanyLua need these fields duplicated */ SETPTR(kb->name, g_strdup(kf_name)); SETPTR(kb->label, g_strdup(label)); } else { /* we don't touch these strings unless group->plugin is set, const cast is safe */ kb->name = (gchar *)kf_name; kb->label = (gchar *)label; } kb->key = key; kb->mods = mod; kb->default_key = key; kb->default_mods = mod; kb->callback = callback; kb->cb_func = NULL; kb->cb_data = NULL; kb->menu_item = menu_item; kb->id = key_id; return kb; } /** Creates a new keybinding using a GeanyKeyBindingFunc and attaches it to a keybinding group * * If given the callback should return @c TRUE if the keybinding was handled, otherwise @c FALSE * to allow other callbacks to be run. This allows for multiplexing keybindings on the same keys, * depending on the focused widget (or context). If the callback is NULL the group's callback will * be invoked, but the same rule applies. * * @param group Group. * @param key_id Keybinding index for the group. * @param key Default key, e.g. @c GDK_KEY_j (must be lower case), but usually 0 for unset. * @param mod Default modifier, e.g. @c GDK_CONTROL_MASK, but usually 0 for unset. * @param kf_name Key name used for this item in the keybindings configuration file, i.e. @c "menu_new". * @param label Label used in the preferences dialog keybindings tab. May contain * underscores - these won't be displayed. * @param menu_item @nullable Optional widget to set an accelerator for, or @c NULL. * @param cb @nullable New-style callback to be called when activated, or @c NULL to use the group callback. * @param pdata Plugin-specific data passed back to the callback @a cb. * @param destroy_notify Function that is invoked to free the plugin data when not needed anymore. * @return @transfer{none} The keybinding - normally this is ignored. * * @since 1.26 (API 226) * @see See plugin_set_key_group_full **/ GEANY_API_SYMBOL GeanyKeyBinding *keybindings_set_item_full(GeanyKeyGroup *group, gsize key_id, guint key, GdkModifierType mod, const gchar *kf_name, const gchar *label, GtkWidget *menu_item, GeanyKeyBindingFunc cb, gpointer pdata, GDestroyNotify destroy_notify) { GeanyKeyBinding *kb; /* For now, this is intended for plugins only */ g_assert(group->plugin); kb = keybindings_set_item(group, key_id, NULL, key, mod, kf_name, label, menu_item); kb->cb_func = cb; kb->cb_data = pdata; kb->cb_data_destroy = destroy_notify; return kb; } static void free_key_binding(gpointer item) { GeanyKeyBinding *kb = item; g_free(kb->name); g_free(kb->label); if (kb->cb_data_destroy) kb->cb_data_destroy(kb->cb_data); } static void add_kb_group(GeanyKeyGroup *group, const gchar *name, const gchar *label, GeanyKeyGroupCallback callback, gboolean plugin) { g_ptr_array_add(keybinding_groups, group); /* as for items, we only require duplicated name and label for plugins */ group->name = plugin ? g_strdup(name) : name; group->label = plugin ? g_strdup(label) : label; group->callback = callback; group->cb_func = NULL; group->cb_data = NULL; group->plugin = plugin; /* Only plugins use the destroy notify thus far */ group->key_items = g_ptr_array_new_with_free_func(plugin ? free_key_binding : NULL); } GeanyKeyGroup *keybindings_get_core_group(guint id) { static GeanyKeyGroup groups[GEANY_KEY_GROUP_COUNT]; g_return_val_if_fail(id < GEANY_KEY_GROUP_COUNT, NULL); return &groups[id]; } static void add_kb(GeanyKeyGroup *group, gsize key_id, GeanyKeyCallback callback, guint key, GdkModifierType mod, const gchar *kf_name, const gchar *label, const gchar *widget_name) { GtkWidget *widget = widget_name ? ui_lookup_widget(main_widgets.window, widget_name) : NULL; keybindings_set_item(group, key_id, callback, key, mod, kf_name, label, widget); } #define ADD_KB_GROUP(group_id, label, callback) \ add_kb_group(keybindings_get_core_group(group_id),\ keybindings_keyfile_group_name, label, callback, FALSE) static void init_default_kb(void) { GeanyKeyGroup *group; /* visual group order */ ADD_KB_GROUP(GEANY_KEY_GROUP_FILE, _("File"), cb_func_file_action); ADD_KB_GROUP(GEANY_KEY_GROUP_EDITOR, _("Editor"), cb_func_editor_action); ADD_KB_GROUP(GEANY_KEY_GROUP_CLIPBOARD, _("Clipboard"), cb_func_clipboard_action); ADD_KB_GROUP(GEANY_KEY_GROUP_SELECT, _("Select"), cb_func_select_action); ADD_KB_GROUP(GEANY_KEY_GROUP_FORMAT, _("Format"), cb_func_format_action); ADD_KB_GROUP(GEANY_KEY_GROUP_INSERT, _("Insert"), cb_func_insert_action); ADD_KB_GROUP(GEANY_KEY_GROUP_SETTINGS, _("Settings"), NULL); ADD_KB_GROUP(GEANY_KEY_GROUP_SEARCH, _("Search"), cb_func_search_action); ADD_KB_GROUP(GEANY_KEY_GROUP_GOTO, _("Go to"), cb_func_goto_action); ADD_KB_GROUP(GEANY_KEY_GROUP_VIEW, _("View"), cb_func_view_action); ADD_KB_GROUP(GEANY_KEY_GROUP_DOCUMENT, _("Document"), cb_func_document_action); ADD_KB_GROUP(GEANY_KEY_GROUP_PROJECT, _("Project"), cb_func_project_action); ADD_KB_GROUP(GEANY_KEY_GROUP_BUILD, _("Build"), build_keybinding); ADD_KB_GROUP(GEANY_KEY_GROUP_TOOLS, _("Tools"), NULL); ADD_KB_GROUP(GEANY_KEY_GROUP_HELP, _("Help"), NULL); ADD_KB_GROUP(GEANY_KEY_GROUP_FOCUS, _("Focus"), cb_func_switch_action); ADD_KB_GROUP(GEANY_KEY_GROUP_NOTEBOOK, _("Notebook tab"), NULL); /* Init all fields of keys with default values. * The menu_item field is always the main menu item, popup menu accelerators are * set in add_popup_menu_accels(). */ group = keybindings_get_core_group(GEANY_KEY_GROUP_FILE); add_kb(group, GEANY_KEYS_FILE_NEW, NULL, GDK_KEY_n, GEANY_PRIMARY_MOD_MASK, "menu_new", _("New"), "menu_new1"); add_kb(group, GEANY_KEYS_FILE_OPEN, NULL, GDK_KEY_o, GEANY_PRIMARY_MOD_MASK, "menu_open", _("Open"), "menu_open1"); add_kb(group, GEANY_KEYS_FILE_OPENSELECTED, NULL, GDK_KEY_o, GDK_SHIFT_MASK | GEANY_PRIMARY_MOD_MASK, "menu_open_selected", _("Open selected file"), "menu_open_selected_file1"); add_kb(group, GEANY_KEYS_FILE_SAVE, NULL, GDK_KEY_s, GEANY_PRIMARY_MOD_MASK, "menu_save", _("Save"), "menu_save1"); add_kb(group, GEANY_KEYS_FILE_SAVEAS, NULL, 0, 0, "menu_saveas", _("Save as"), "menu_save_as1"); add_kb(group, GEANY_KEYS_FILE_SAVEALL, NULL, GDK_KEY_s, GDK_SHIFT_MASK | GEANY_PRIMARY_MOD_MASK, "menu_saveall", _("Save all"), "menu_save_all1"); add_kb(group, GEANY_KEYS_FILE_PROPERTIES, NULL, GDK_KEY_v, GDK_SHIFT_MASK | GEANY_PRIMARY_MOD_MASK, "file_properties", _("Properties"), "properties1"); add_kb(group, GEANY_KEYS_FILE_PRINT, NULL, GDK_KEY_p, GEANY_PRIMARY_MOD_MASK, "menu_print", _("Print"), "print1"); add_kb(group, GEANY_KEYS_FILE_CLOSE, NULL, GDK_KEY_w, GEANY_PRIMARY_MOD_MASK, "menu_close", _("Close"), "menu_close1"); add_kb(group, GEANY_KEYS_FILE_CLOSEALL, NULL, GDK_KEY_w, GEANY_PRIMARY_MOD_MASK | GDK_SHIFT_MASK, "menu_closeall", _("Close all"), "menu_close_all1"); add_kb(group, GEANY_KEYS_FILE_RELOAD, NULL, GDK_KEY_r, GEANY_PRIMARY_MOD_MASK, "menu_reloadfile", _("Reload file"), "menu_reload1"); add_kb(group, GEANY_KEYS_FILE_RELOAD_ALL, NULL, 0, 0, "menu_reloadall", _("Reload all files"), NULL); add_kb(group, GEANY_KEYS_FILE_OPENLASTTAB, NULL, 0, 0, "file_openlasttab", _("Re-open last closed tab"), NULL); add_kb(group, GEANY_KEYS_FILE_QUIT, NULL, GDK_KEY_q, GEANY_PRIMARY_MOD_MASK, "menu_quit", _("Quit"), "menu_quit1"); group = keybindings_get_core_group(GEANY_KEY_GROUP_PROJECT); add_kb(group, GEANY_KEYS_PROJECT_NEW, NULL, 0, 0, "project_new", _("New"), "project_new1"); add_kb(group, GEANY_KEYS_PROJECT_NEW_FROM_FOLDER, NULL, 0, 0, "project_new_from_folder", _("New from Folder"), "project_new_from_folder1"); add_kb(group, GEANY_KEYS_PROJECT_OPEN, NULL, 0, 0, "project_open", _("Open"), "project_open1"); add_kb(group, GEANY_KEYS_PROJECT_PROPERTIES, NULL, 0, 0, "project_properties", ui_lookup_stock_label(GTK_STOCK_PROPERTIES), "project_properties1"); add_kb(group, GEANY_KEYS_PROJECT_CLOSE, NULL, 0, 0, "project_close", _("Close"), "project_close1"); group = keybindings_get_core_group(GEANY_KEY_GROUP_EDITOR); add_kb(group, GEANY_KEYS_EDITOR_UNDO, NULL, GDK_KEY_z, GEANY_PRIMARY_MOD_MASK, "menu_undo", _("Undo"), "menu_undo2"); add_kb(group, GEANY_KEYS_EDITOR_REDO, NULL, GDK_KEY_y, GEANY_PRIMARY_MOD_MASK, "menu_redo", _("Redo"), "menu_redo2"); add_kb(group, GEANY_KEYS_EDITOR_DUPLICATELINE, NULL, GDK_KEY_d, GEANY_PRIMARY_MOD_MASK, "edit_duplicateline", _("D_uplicate Line or Selection"), "duplicate_line_or_selection1"); add_kb(group, GEANY_KEYS_EDITOR_DELETELINE, NULL, GDK_KEY_k, GEANY_PRIMARY_MOD_MASK, "edit_deleteline", _("_Delete Current Line(s)"), "delete_current_lines1"); add_kb(group, GEANY_KEYS_EDITOR_DELETELINETOEND, NULL, GDK_KEY_Delete, GDK_SHIFT_MASK | GEANY_PRIMARY_MOD_MASK, "edit_deletelinetoend", _("Delete to line end"), NULL); add_kb(group, GEANY_KEYS_EDITOR_DELETELINETOBEGINNING, NULL, GDK_KEY_BackSpace, GDK_SHIFT_MASK | GEANY_PRIMARY_MOD_MASK, "edit_deletelinetobegin", _("Delete to beginning of line"), NULL); /* Note: transpose may fit better in format group, but that would break the API */ add_kb(group, GEANY_KEYS_EDITOR_TRANSPOSELINE, NULL, 0, 0, "edit_transposeline", _("_Transpose Current Line"), NULL); add_kb(group, GEANY_KEYS_EDITOR_SCROLLTOLINE, NULL, GDK_KEY_l, GDK_SHIFT_MASK | GEANY_PRIMARY_MOD_MASK, "edit_scrolltoline", _("Scroll to current line"), NULL); add_kb(group, GEANY_KEYS_EDITOR_SCROLLLINEUP, NULL, GDK_KEY_Up, GDK_MOD1_MASK, "edit_scrolllineup", _("Scroll up the view by one line"), NULL); add_kb(group, GEANY_KEYS_EDITOR_SCROLLLINEDOWN, NULL, GDK_KEY_Down, GDK_MOD1_MASK, "edit_scrolllinedown", _("Scroll down the view by one line"), NULL); add_kb(group, GEANY_KEYS_EDITOR_COMPLETESNIPPET, NULL, GDK_KEY_Tab, 0, "edit_completesnippet", _("Complete snippet"), NULL); add_kb(group, GEANY_KEYS_EDITOR_SNIPPETNEXTCURSOR, NULL, 0, 0, "move_snippetnextcursor", _("Move cursor in snippet"), NULL); add_kb(group, GEANY_KEYS_EDITOR_SUPPRESSSNIPPETCOMPLETION, NULL, 0, 0, "edit_suppresssnippetcompletion", _("Suppress snippet completion"), NULL); add_kb(group, GEANY_KEYS_EDITOR_CONTEXTACTION, NULL, 0, 0, "popup_contextaction", _("Context Action"), NULL); add_kb(group, GEANY_KEYS_EDITOR_AUTOCOMPLETE, NULL, GDK_KEY_space, GEANY_PRIMARY_MOD_MASK, "edit_autocomplete", _("Complete word"), NULL); add_kb(group, GEANY_KEYS_EDITOR_CALLTIP, NULL, GDK_KEY_space, GEANY_PRIMARY_MOD_MASK | GDK_SHIFT_MASK, "edit_calltip", _("Show calltip"), NULL); add_kb(group, GEANY_KEYS_EDITOR_WORDPARTCOMPLETION, NULL, GDK_KEY_Tab, 0, "edit_wordpartcompletion", _("Word part completion"), NULL); add_kb(group, GEANY_KEYS_EDITOR_MOVELINEUP, NULL, GDK_KEY_Page_Up, GDK_MOD1_MASK, "edit_movelineup", _("Move line(s) up"), "move_lines_up1"); add_kb(group, GEANY_KEYS_EDITOR_MOVELINEDOWN, NULL, GDK_KEY_Page_Down, GDK_MOD1_MASK, "edit_movelinedown", _("Move line(s) down"), "move_lines_down1"); group = keybindings_get_core_group(GEANY_KEY_GROUP_CLIPBOARD); add_kb(group, GEANY_KEYS_CLIPBOARD_CUT, NULL, GDK_KEY_x, GEANY_PRIMARY_MOD_MASK, "menu_cut", _("Cut"), "menu_cut1"); add_kb(group, GEANY_KEYS_CLIPBOARD_COPY, NULL, GDK_KEY_c, GEANY_PRIMARY_MOD_MASK, "menu_copy", _("Copy"), "menu_copy1"); add_kb(group, GEANY_KEYS_CLIPBOARD_PASTE, NULL, GDK_KEY_v, GEANY_PRIMARY_MOD_MASK, "menu_paste", _("Paste"), "menu_paste1"); add_kb(group, GEANY_KEYS_CLIPBOARD_COPYLINE, NULL, GDK_KEY_c, GEANY_PRIMARY_MOD_MASK | GDK_SHIFT_MASK, "edit_copyline", _("_Copy Current Line(s)"), "copy_current_lines1"); add_kb(group, GEANY_KEYS_CLIPBOARD_CUTLINE, NULL, GDK_KEY_x, GEANY_PRIMARY_MOD_MASK | GDK_SHIFT_MASK, "edit_cutline", _("Cu_t Current Line(s)"), "cut_current_lines1"); group = keybindings_get_core_group(GEANY_KEY_GROUP_SELECT); add_kb(group, GEANY_KEYS_SELECT_ALL, NULL, GDK_KEY_a, GEANY_PRIMARY_MOD_MASK, "menu_selectall", _("Select All"), "menu_select_all1"); add_kb(group, GEANY_KEYS_SELECT_WORD, NULL, GDK_KEY_w, GDK_SHIFT_MASK | GDK_MOD1_MASK, "edit_selectword", _("Select current word"), NULL); add_kb(group, GEANY_KEYS_SELECT_LINE, NULL, GDK_KEY_l, GDK_SHIFT_MASK | GDK_MOD1_MASK, "edit_selectline", _("S_elect Current Line(s)"), "select_current_lines1"); add_kb(group, GEANY_KEYS_SELECT_PARAGRAPH, NULL, GDK_KEY_p, GDK_SHIFT_MASK | GDK_MOD1_MASK, "edit_selectparagraph", _("Se_lect Current Paragraph"), "select_current_paragraph1"); add_kb(group, GEANY_KEYS_SELECT_WORDPARTLEFT, NULL, 0, 0, "edit_selectwordpartleft", _("Select to previous word part"), NULL); add_kb(group, GEANY_KEYS_SELECT_WORDPARTRIGHT, NULL, 0, 0, "edit_selectwordpartright", _("Select to next word part"), NULL); group = keybindings_get_core_group(GEANY_KEY_GROUP_FORMAT); add_kb(group, GEANY_KEYS_FORMAT_TOGGLECASE, NULL, GDK_KEY_u, GEANY_PRIMARY_MOD_MASK | GDK_MOD1_MASK, "edit_togglecase", _("T_oggle Case of Selection"), "menu_toggle_case2"); add_kb(group, GEANY_KEYS_FORMAT_COMMENTLINETOGGLE, NULL, GDK_KEY_e, GEANY_PRIMARY_MOD_MASK, "edit_commentlinetoggle", _("Toggle line commentation"), "menu_toggle_line_commentation1"); add_kb(group, GEANY_KEYS_FORMAT_COMMENTLINE, NULL, 0, 0, "edit_commentline", _("Comment line(s)"), "menu_comment_line1"); add_kb(group, GEANY_KEYS_FORMAT_UNCOMMENTLINE, NULL, 0, 0, "edit_uncommentline", _("Uncomment line(s)"), "menu_uncomment_line1"); add_kb(group, GEANY_KEYS_FORMAT_INCREASEINDENT, NULL, GDK_KEY_i, GEANY_PRIMARY_MOD_MASK, "edit_increaseindent", _("Increase indent"), "menu_increase_indent1"); add_kb(group, GEANY_KEYS_FORMAT_DECREASEINDENT, NULL, GDK_KEY_u, GEANY_PRIMARY_MOD_MASK, "edit_decreaseindent", _("Decrease indent"), "menu_decrease_indent1"); add_kb(group, GEANY_KEYS_FORMAT_INCREASEINDENTBYSPACE, NULL, 0, 0, "edit_increaseindentbyspace", _("Increase indent by one space"), NULL); add_kb(group, GEANY_KEYS_FORMAT_DECREASEINDENTBYSPACE, NULL, 0, 0, "edit_decreaseindentbyspace", _("Decrease indent by one space"), NULL); add_kb(group, GEANY_KEYS_FORMAT_AUTOINDENT, NULL, 0, 0, "edit_autoindent", _("S_mart Line Indent"), "smart_line_indent1"); add_kb(group, GEANY_KEYS_FORMAT_SENDTOCMD1, NULL, GDK_KEY_1, GEANY_PRIMARY_MOD_MASK, "edit_sendtocmd1", _("Send to Custom Command 1"), NULL); add_kb(group, GEANY_KEYS_FORMAT_SENDTOCMD2, NULL, GDK_KEY_2, GEANY_PRIMARY_MOD_MASK, "edit_sendtocmd2", _("Send to Custom Command 2"), NULL); add_kb(group, GEANY_KEYS_FORMAT_SENDTOCMD3, NULL, GDK_KEY_3, GEANY_PRIMARY_MOD_MASK, "edit_sendtocmd3", _("Send to Custom Command 3"), NULL); add_kb(group, GEANY_KEYS_FORMAT_SENDTOCMD4, NULL, 0, 0, "edit_sendtocmd4", _("Send to Custom Command 4"), NULL); add_kb(group, GEANY_KEYS_FORMAT_SENDTOCMD5, NULL, 0, 0, "edit_sendtocmd5", _("Send to Custom Command 5"), NULL); add_kb(group, GEANY_KEYS_FORMAT_SENDTOCMD6, NULL, 0, 0, "edit_sendtocmd6", _("Send to Custom Command 6"), NULL); add_kb(group, GEANY_KEYS_FORMAT_SENDTOCMD7, NULL, 0, 0, "edit_sendtocmd7", _("Send to Custom Command 7"), NULL); add_kb(group, GEANY_KEYS_FORMAT_SENDTOCMD8, NULL, 0, 0, "edit_sendtocmd8", _("Send to Custom Command 8"), NULL); add_kb(group, GEANY_KEYS_FORMAT_SENDTOCMD9, NULL, 0, 0, "edit_sendtocmd9", _("Send to Custom Command 9"), NULL); /* may fit better in editor group */ add_kb(group, GEANY_KEYS_FORMAT_SENDTOVTE, NULL, 0, 0, "edit_sendtovte", _("_Send Selection to Terminal"), "send_selection_to_vte1"); add_kb(group, GEANY_KEYS_FORMAT_REFLOWPARAGRAPH, NULL, GDK_KEY_j, GEANY_PRIMARY_MOD_MASK, "format_reflowparagraph", _("_Reflow Lines/Block"), "reflow_lines_block1"); add_kb(group, GEANY_KEYS_FORMAT_JOINLINES, NULL, 0, 0, "edit_joinlines", _("_Join Lines"), "join_lines1"); group = keybindings_get_core_group(GEANY_KEY_GROUP_INSERT); add_kb(group, GEANY_KEYS_INSERT_DATE, NULL, GDK_KEY_d, GDK_SHIFT_MASK | GDK_MOD1_MASK, "menu_insert_date", _("Insert date"), "insert_date_custom1"); add_kb(group, GEANY_KEYS_INSERT_ALTWHITESPACE, NULL, 0, 0, "edit_insertwhitespace", _("Insert Alternative _White Space"), "insert_alternative_white_space1"); add_kb(group, GEANY_KEYS_INSERT_LINEBEFORE, NULL, 0, 0, "edit_insertlinebefore", _("Insert New Line Before Current"), NULL); add_kb(group, GEANY_KEYS_INSERT_LINEAFTER, NULL, 0, 0, "edit_insertlineafter", _("Insert New Line After Current"), NULL); group = keybindings_get_core_group(GEANY_KEY_GROUP_SETTINGS); add_kb(group, GEANY_KEYS_SETTINGS_PREFERENCES, cb_func_menu_preferences, GDK_KEY_p, GEANY_PRIMARY_MOD_MASK | GDK_MOD1_MASK, "menu_preferences", _("Preferences"), "preferences1"); add_kb(group, GEANY_KEYS_SETTINGS_PLUGINPREFERENCES, cb_func_menu_preferences, 0, 0, "menu_pluginpreferences", _("P_lugin Preferences"), "plugin_preferences1"); group = keybindings_get_core_group(GEANY_KEY_GROUP_SEARCH); add_kb(group, GEANY_KEYS_SEARCH_FIND, NULL, GDK_KEY_f, GEANY_PRIMARY_MOD_MASK, "menu_find", _("Find"), "find1"); add_kb(group, GEANY_KEYS_SEARCH_FINDNEXT, NULL, GDK_KEY_g, GEANY_PRIMARY_MOD_MASK, "menu_findnext", _("Find Next"), "find_next1"); add_kb(group, GEANY_KEYS_SEARCH_FINDPREVIOUS, NULL, GDK_KEY_g, GEANY_PRIMARY_MOD_MASK | GDK_SHIFT_MASK, "menu_findprevious", _("Find Previous"), "find_previous1"); add_kb(group, GEANY_KEYS_SEARCH_FINDNEXTSEL, NULL, 0, 0, "menu_findnextsel", _("Find Next _Selection"), "find_nextsel1"); add_kb(group, GEANY_KEYS_SEARCH_FINDPREVSEL, NULL, 0, 0, "menu_findprevsel", _("Find Pre_vious Selection"), "find_prevsel1"); add_kb(group, GEANY_KEYS_SEARCH_REPLACE, NULL, GDK_KEY_h, GEANY_PRIMARY_MOD_MASK, "menu_replace", _("Replace"), "replace1"); add_kb(group, GEANY_KEYS_SEARCH_FINDINFILES, NULL, GDK_KEY_f, GEANY_PRIMARY_MOD_MASK | GDK_SHIFT_MASK, "menu_findinfiles", _("Find in Files"), "find_in_files1"); add_kb(group, GEANY_KEYS_SEARCH_NEXTMESSAGE, NULL, 0, 0, "menu_nextmessage", _("Next Message"), "next_message1"); add_kb(group, GEANY_KEYS_SEARCH_PREVIOUSMESSAGE, NULL, 0, 0, "menu_previousmessage", _("Previous Message"), "previous_message1"); add_kb(group, GEANY_KEYS_SEARCH_FINDUSAGE, NULL, GDK_KEY_e, GEANY_PRIMARY_MOD_MASK | GDK_SHIFT_MASK, "popup_findusage", _("Find Usage"), "find_usage1"); add_kb(group, GEANY_KEYS_SEARCH_FINDDOCUMENTUSAGE, NULL, GDK_KEY_d, GEANY_PRIMARY_MOD_MASK | GDK_SHIFT_MASK, "popup_finddocumentusage", _("Find Document Usage"), "find_document_usage1"); add_kb(group, GEANY_KEYS_SEARCH_MARKALL, NULL, GDK_KEY_m, GEANY_PRIMARY_MOD_MASK | GDK_SHIFT_MASK, "find_markall", _("_Mark All"), "mark_all1"); group = keybindings_get_core_group(GEANY_KEY_GROUP_GOTO); add_kb(group, GEANY_KEYS_GOTO_BACK, NULL, GDK_KEY_Left, GDK_MOD1_MASK, "nav_back", _("Navigate back a location"), NULL); add_kb(group, GEANY_KEYS_GOTO_FORWARD, NULL, GDK_KEY_Right, GDK_MOD1_MASK, "nav_forward", _("Navigate forward a location"), NULL); add_kb(group, GEANY_KEYS_GOTO_LINE, NULL, GDK_KEY_l, GEANY_PRIMARY_MOD_MASK, "menu_gotoline", _("Go to Line"), "go_to_line1"); add_kb(group, GEANY_KEYS_GOTO_MATCHINGBRACE, NULL, GDK_KEY_b, GEANY_PRIMARY_MOD_MASK, "edit_gotomatchingbrace", _("Go to matching brace"), NULL); add_kb(group, GEANY_KEYS_GOTO_TOGGLEMARKER, NULL, GDK_KEY_m, GEANY_PRIMARY_MOD_MASK, "edit_togglemarker", _("Toggle marker"), NULL); add_kb(group, GEANY_KEYS_GOTO_NEXTMARKER, NULL, GDK_KEY_period, GEANY_PRIMARY_MOD_MASK, "edit_gotonextmarker", _("Go to Ne_xt Marker"), "go_to_next_marker1"); add_kb(group, GEANY_KEYS_GOTO_PREVIOUSMARKER, NULL, GDK_KEY_comma, GEANY_PRIMARY_MOD_MASK, "edit_gotopreviousmarker", _("Go to Pre_vious Marker"), "go_to_previous_marker1"); add_kb(group, GEANY_KEYS_GOTO_TAGDEFINITION, NULL, GDK_KEY_t, GEANY_PRIMARY_MOD_MASK, "popup_gototagdefinition", _("Go to Symbol Definition"), "goto_tag_definition1"); add_kb(group, GEANY_KEYS_GOTO_TAGDECLARATION, NULL, GDK_KEY_t, GEANY_PRIMARY_MOD_MASK | GDK_SHIFT_MASK, "popup_gototagdeclaration", _("Go to Symbol Declaration"), "goto_tag_declaration1"); add_kb(group, GEANY_KEYS_GOTO_LINESTART, NULL, GDK_KEY_Home, 0, "edit_gotolinestart", _("Go to Start of Line"), NULL); add_kb(group, GEANY_KEYS_GOTO_LINEEND, NULL, GDK_KEY_End, 0, "edit_gotolineend", _("Go to End of Line"), NULL); add_kb(group, GEANY_KEYS_GOTO_LINESTARTVISUAL, NULL, GDK_KEY_Home, GDK_MOD1_MASK, "edit_gotolinestartvisual", _("Go to Start of Display Line"), NULL); add_kb(group, GEANY_KEYS_GOTO_LINEENDVISUAL, NULL, GDK_KEY_End, GDK_MOD1_MASK, "edit_gotolineendvisual", _("Go to End of Display Line"), NULL); add_kb(group, GEANY_KEYS_GOTO_PREVWORDPART, NULL, GDK_KEY_slash, GEANY_PRIMARY_MOD_MASK, "edit_prevwordstart", _("Go to Previous Word Part"), NULL); add_kb(group, GEANY_KEYS_GOTO_NEXTWORDPART, NULL, GDK_KEY_backslash, GEANY_PRIMARY_MOD_MASK, "edit_nextwordstart", _("Go to Next Word Part"), NULL); group = keybindings_get_core_group(GEANY_KEY_GROUP_VIEW); add_kb(group, GEANY_KEYS_VIEW_TOGGLEALL, NULL, 0, 0, "menu_toggleall", _("Toggle All Additional Widgets"), "menu_toggle_all_additional_widgets1"); add_kb(group, GEANY_KEYS_VIEW_FULLSCREEN, cb_func_menu_fullscreen, GDK_KEY_F11, 0, "menu_fullscreen", _("Fullscreen"), "menu_fullscreen1"); add_kb(group, GEANY_KEYS_VIEW_MESSAGEWINDOW, cb_func_menu_messagewindow, 0, 0, "menu_messagewindow", _("Toggle Messages Window"), "menu_show_messages_window1"); add_kb(group, GEANY_KEYS_VIEW_SIDEBAR, NULL, 0, 0, "toggle_sidebar", _("Toggle Sidebar"), "menu_show_sidebar1"); add_kb(group, GEANY_KEYS_VIEW_ZOOMIN, NULL, GDK_KEY_plus, GEANY_PRIMARY_MOD_MASK, "menu_zoomin", _("Zoom In"), "menu_zoom_in1"); add_kb(group, GEANY_KEYS_VIEW_ZOOMOUT, NULL, GDK_KEY_minus, GEANY_PRIMARY_MOD_MASK, "menu_zoomout", _("Zoom Out"), "menu_zoom_out1"); add_kb(group, GEANY_KEYS_VIEW_ZOOMRESET, NULL, GDK_KEY_0, GEANY_PRIMARY_MOD_MASK, "normal_size", _("Zoom Reset"), "normal_size1"); group = keybindings_get_core_group(GEANY_KEY_GROUP_FOCUS); add_kb(group, GEANY_KEYS_FOCUS_EDITOR, NULL, GDK_KEY_F2, 0, "switch_editor", _("Switch to Editor"), NULL); add_kb(group, GEANY_KEYS_FOCUS_SEARCHBAR, NULL, GDK_KEY_F7, 0, "switch_search_bar", _("Switch to Search Bar"), NULL); add_kb(group, GEANY_KEYS_FOCUS_MESSAGE_WINDOW, NULL, 0, 0, "switch_message_window", _("Switch to Message Window"), NULL); add_kb(group, GEANY_KEYS_FOCUS_COMPILER, NULL, 0, 0, "switch_compiler", _("Switch to Compiler"), NULL); add_kb(group, GEANY_KEYS_FOCUS_MESSAGES, NULL, 0, 0, "switch_messages", _("Switch to Messages"), NULL); add_kb(group, GEANY_KEYS_FOCUS_SCRIBBLE, NULL, GDK_KEY_F6, 0, "switch_scribble", _("Switch to Scribble"), NULL); add_kb(group, GEANY_KEYS_FOCUS_VTE, NULL, GDK_KEY_F4, 0, "switch_vte", _("Switch to VTE"), NULL); add_kb(group, GEANY_KEYS_FOCUS_SIDEBAR, NULL, 0, 0, "switch_sidebar", _("Switch to Sidebar"), NULL); add_kb(group, GEANY_KEYS_FOCUS_SIDEBAR_SYMBOL_LIST, NULL, 0, 0, "switch_sidebar_symbol_list", _("Switch to Sidebar Symbol List"), NULL); add_kb(group, GEANY_KEYS_FOCUS_SIDEBAR_DOCUMENT_LIST, NULL, 0, 0, "switch_sidebar_doc_list", _("Switch to Sidebar Document List"), NULL); group = keybindings_get_core_group(GEANY_KEY_GROUP_NOTEBOOK); add_kb(group, GEANY_KEYS_NOTEBOOK_SWITCHTABLEFT, cb_func_switch_tableft, GDK_KEY_Page_Up, GEANY_PRIMARY_MOD_MASK, "switch_tableft", _("Switch to left document"), NULL); add_kb(group, GEANY_KEYS_NOTEBOOK_SWITCHTABRIGHT, cb_func_switch_tabright, GDK_KEY_Page_Down, GEANY_PRIMARY_MOD_MASK, "switch_tabright", _("Switch to right document"), NULL); add_kb(group, GEANY_KEYS_NOTEBOOK_SWITCHTABLASTUSED, cb_func_switch_tablastused, GDK_KEY_Tab, GEANY_PRIMARY_MOD_MASK, "switch_tablastused", _("Switch to last used document"), NULL); add_kb(group, GEANY_KEYS_NOTEBOOK_MOVETABLEFT, cb_func_move_tab, GDK_KEY_Page_Up, GEANY_PRIMARY_MOD_MASK | GDK_SHIFT_MASK, "move_tableft", _("Move document left"), NULL); add_kb(group, GEANY_KEYS_NOTEBOOK_MOVETABRIGHT, cb_func_move_tab, GDK_KEY_Page_Down, GEANY_PRIMARY_MOD_MASK | GDK_SHIFT_MASK, "move_tabright", _("Move document right"), NULL); add_kb(group, GEANY_KEYS_NOTEBOOK_MOVETABFIRST, cb_func_move_tab, 0, 0, "move_tabfirst", _("Move document first"), NULL); add_kb(group, GEANY_KEYS_NOTEBOOK_MOVETABLAST, cb_func_move_tab, 0, 0, "move_tablast", _("Move document last"), NULL); group = keybindings_get_core_group(GEANY_KEY_GROUP_DOCUMENT); add_kb(group, GEANY_KEYS_DOCUMENT_LINEWRAP, NULL, 0, 0, "menu_linewrap", _("Toggle Line wrapping"), "menu_line_wrapping1"); add_kb(group, GEANY_KEYS_DOCUMENT_LINEBREAK, NULL, 0, 0, "menu_linebreak", _("Toggle Line breaking"), "line_breaking1"); add_kb(group, GEANY_KEYS_DOCUMENT_CLONE, NULL, 0, 0, "menu_clone", _("_Clone"), "clone1"); add_kb(group, GEANY_KEYS_DOCUMENT_STRIPTRAILINGSPACES, NULL, 0, 0, "menu_strip_trailing_spaces", _("_Strip Trailing Spaces"), "strip_trailing_spaces1"); add_kb(group, GEANY_KEYS_DOCUMENT_REPLACETABS, NULL, 0, 0, "menu_replacetabs", _("Replace tabs with space"), "menu_replace_tabs"); add_kb(group, GEANY_KEYS_DOCUMENT_REPLACESPACES, NULL, 0, 0, "menu_replacespaces", _("Replace spaces with tabs"), "menu_replace_spaces"); add_kb(group, GEANY_KEYS_DOCUMENT_TOGGLEFOLD, NULL, 0, 0, "menu_togglefold", _("Toggle current fold"), NULL); add_kb(group, GEANY_KEYS_DOCUMENT_FOLDALL, NULL, 0, 0, "menu_foldall", _("Fold all"), "menu_fold_all1"); add_kb(group, GEANY_KEYS_DOCUMENT_UNFOLDALL, NULL, 0, 0, "menu_unfoldall", _("Unfold all"), "menu_unfold_all1"); add_kb(group, GEANY_KEYS_DOCUMENT_RELOADTAGLIST, NULL, GDK_KEY_r, GDK_SHIFT_MASK | GEANY_PRIMARY_MOD_MASK, "reloadtaglist", _("Reload symbol list"), NULL); add_kb(group, GEANY_KEYS_DOCUMENT_REMOVE_MARKERS, NULL, 0, 0, "remove_markers", _("Remove Markers"), "remove_markers1"); add_kb(group, GEANY_KEYS_DOCUMENT_REMOVE_ERROR_INDICATORS, NULL, 0, 0, "remove_error_indicators", _("Remove Error Indicators"), "menu_remove_indicators1"); add_kb(group, GEANY_KEYS_DOCUMENT_REMOVE_MARKERS_INDICATORS, NULL, 0, 0, "remove_markers_and_indicators", _("Remove Markers and Error Indicators"), NULL); group = keybindings_get_core_group(GEANY_KEY_GROUP_BUILD); add_kb(group, GEANY_KEYS_BUILD_COMPILE, NULL, GDK_KEY_F8, 0, "build_compile", _("Compile"), NULL); add_kb(group, GEANY_KEYS_BUILD_LINK, NULL, GDK_KEY_F9, 0, "build_link", _("Build"), NULL); add_kb(group, GEANY_KEYS_BUILD_MAKE, NULL, GDK_KEY_F9, GDK_SHIFT_MASK, "build_make", _("Make all"), NULL); add_kb(group, GEANY_KEYS_BUILD_MAKEOWNTARGET, NULL, GDK_KEY_F9, GDK_SHIFT_MASK | GEANY_PRIMARY_MOD_MASK, "build_makeowntarget", _("Make custom target"), NULL); add_kb(group, GEANY_KEYS_BUILD_MAKEOBJECT, NULL, GDK_KEY_F8, GDK_SHIFT_MASK, "build_makeobject", _("Make object"), NULL); add_kb(group, GEANY_KEYS_BUILD_NEXTERROR, NULL, 0, 0, "build_nexterror", _("Next error"), NULL); add_kb(group, GEANY_KEYS_BUILD_PREVIOUSERROR, NULL, 0, 0, "build_previouserror", _("Previous error"), NULL); add_kb(group, GEANY_KEYS_BUILD_RUN, NULL, GDK_KEY_F5, 0, "build_run", _("Run"), NULL); add_kb(group, GEANY_KEYS_BUILD_OPTIONS, NULL, 0, 0, "build_options", _("Build options"), NULL); group = keybindings_get_core_group(GEANY_KEY_GROUP_TOOLS); add_kb(group, GEANY_KEYS_TOOLS_OPENCOLORCHOOSER, cb_func_menu_opencolorchooser, 0, 0, "menu_opencolorchooser", _("Show Color Chooser"), "menu_choose_color1"); group = keybindings_get_core_group(GEANY_KEY_GROUP_HELP); add_kb(group, GEANY_KEYS_HELP_HELP, cb_func_menu_help, GDK_KEY_F1, 0, "menu_help", _("Help"), "help1"); } static void free_key_group(gpointer item) { GeanyKeyGroup *group = item; g_ptr_array_free(group->key_items, TRUE); if (group->plugin) { if (group->cb_data_destroy) group->cb_data_destroy(group->cb_data); g_free(group->plugin_keys); /* we allocated those in add_kb_group() as it's a plugin group */ g_free((gchar *) group->name); g_free((gchar *) group->label); g_free(group); } } void keybindings_init(void) { memset(binding_ids, 0, sizeof binding_ids); keybinding_groups = g_ptr_array_sized_new(GEANY_KEY_GROUP_COUNT); g_ptr_array_set_free_func(keybinding_groups, free_key_group); kb_accel_group = gtk_accel_group_new(); init_default_kb(); gtk_window_add_accel_group(GTK_WINDOW(main_widgets.window), kb_accel_group); g_signal_connect(main_widgets.window, "key-press-event", G_CALLBACK(on_key_press_event), NULL); } typedef void (*KBItemCallback) (GeanyKeyGroup *group, GeanyKeyBinding *kb, gpointer user_data); static void keybindings_foreach(KBItemCallback cb, gpointer user_data) { gsize g, i; GeanyKeyGroup *group; GeanyKeyBinding *kb; foreach_ptr_array(group, g, keybinding_groups) { foreach_ptr_array(kb, i, group->key_items) cb(group, kb, user_data); } } static void load_kb(GeanyKeyGroup *group, GeanyKeyBinding *kb, gpointer user_data) { GKeyFile *config = user_data; gchar *val; guint key; GdkModifierType mods; val = g_key_file_get_string(config, group->name, kb->name, NULL); if (val != NULL) { gtk_accelerator_parse(val, &key, &mods); kb->key = key; kb->mods = mods; g_free(val); } } static void load_user_kb(void) { gchar *configfile = g_build_filename(app->configdir, "keybindings.conf", NULL); GKeyFile *config = g_key_file_new(); /* backwards compatibility with Geany 0.21 defaults */ if (!g_file_test(configfile, G_FILE_TEST_EXISTS)) { gchar *geanyconf = g_build_filename(app->configdir, "geany.conf", NULL); const gchar data[] = "[Bindings]\n" "popup_gototagdefinition=\n" "edit_transposeline=t\n" "edit_movelineup=\n" "edit_movelinedown=\n" "move_tableft=Page_Up\n" "move_tabright=Page_Down\n"; utils_write_file(configfile, g_file_test(geanyconf, G_FILE_TEST_EXISTS) ? data : ""); g_free(geanyconf); } /* now load user defined keys */ if (g_key_file_load_from_file(config, configfile, G_KEY_FILE_KEEP_COMMENTS, NULL)) { keybindings_foreach(load_kb, config); } g_free(configfile); g_key_file_free(config); } static void apply_kb_accel(GeanyKeyGroup *group, GeanyKeyBinding *kb, gpointer user_data) { if (kb->key != 0 && kb->menu_item) { gtk_widget_add_accelerator(kb->menu_item, "activate", kb_accel_group, kb->key, kb->mods, GTK_ACCEL_VISIBLE); } } /** Reloads keybinding settings from configuration file. * * Normally plugins do not need to call this function as it is called automatically when a * the plugin is activated. However, plugins which need to create keybindings dynamically * and reload them when needed should call this function after all keybindings have been * updated with plugin_set_key_group() and keybindings_set_item() calls - this makes sure * that the corresponding user keybinding shortcuts are applied. * * @since 1.32 (API 233) */ GEANY_API_SYMBOL void keybindings_load_keyfile(void) { load_user_kb(); add_popup_menu_accels(); /* set menu accels now, after user keybindings have been read */ keybindings_foreach(apply_kb_accel, NULL); } static void add_menu_accel(GeanyKeyGroup *group, guint kb_id, GtkWidget *menuitem) { GeanyKeyBinding *kb = keybindings_get_item(group, kb_id); if (kb->key != 0) gtk_widget_add_accelerator(menuitem, "activate", kb_accel_group, kb->key, kb->mods, GTK_ACCEL_VISIBLE); } #define GEANY_ADD_POPUP_ACCEL(kb_id, wid) \ add_menu_accel(group, kb_id, ui_lookup_widget(main_widgets.editor_menu, G_STRINGIFY(wid))) /* set the menu item accelerator shortcuts (just for visibility, they are handled anyway) */ /* FIXME: update those during runtime */ static void add_popup_menu_accels(void) { GeanyKeyGroup *group; group = keybindings_get_core_group(GEANY_KEY_GROUP_EDITOR); GEANY_ADD_POPUP_ACCEL(GEANY_KEYS_EDITOR_UNDO, undo1); GEANY_ADD_POPUP_ACCEL(GEANY_KEYS_EDITOR_REDO, redo1); GEANY_ADD_POPUP_ACCEL(GEANY_KEYS_EDITOR_CONTEXTACTION, context_action1); group = keybindings_get_core_group(GEANY_KEY_GROUP_CLIPBOARD); GEANY_ADD_POPUP_ACCEL(GEANY_KEYS_CLIPBOARD_CUT, cut1); GEANY_ADD_POPUP_ACCEL(GEANY_KEYS_CLIPBOARD_COPY, copy1); GEANY_ADD_POPUP_ACCEL(GEANY_KEYS_CLIPBOARD_PASTE, paste1); group = keybindings_get_core_group(GEANY_KEY_GROUP_SELECT); GEANY_ADD_POPUP_ACCEL(GEANY_KEYS_SELECT_ALL, menu_select_all2); group = keybindings_get_core_group(GEANY_KEY_GROUP_INSERT); GEANY_ADD_POPUP_ACCEL(GEANY_KEYS_INSERT_DATE, insert_date_custom2); GEANY_ADD_POPUP_ACCEL(GEANY_KEYS_INSERT_ALTWHITESPACE, insert_alternative_white_space2); group = keybindings_get_core_group(GEANY_KEY_GROUP_FILE); GEANY_ADD_POPUP_ACCEL(GEANY_KEYS_FILE_OPENSELECTED, menu_open_selected_file2); group = keybindings_get_core_group(GEANY_KEY_GROUP_SEARCH); GEANY_ADD_POPUP_ACCEL(GEANY_KEYS_SEARCH_FINDUSAGE, find_usage2); GEANY_ADD_POPUP_ACCEL(GEANY_KEYS_SEARCH_FINDDOCUMENTUSAGE, find_document_usage2); group = keybindings_get_core_group(GEANY_KEY_GROUP_GOTO); GEANY_ADD_POPUP_ACCEL(GEANY_KEYS_GOTO_TAGDEFINITION, goto_tag_definition2); /* Format and Commands share the menu bar submenus */ /* Build menu items are set if the build menus are created */ } static void set_keyfile_kb(GeanyKeyGroup *group, GeanyKeyBinding *kb, gpointer user_data) { GKeyFile *config = user_data; gchar *val; val = gtk_accelerator_name(kb->key, kb->mods); g_key_file_set_string(config, group->name, kb->name, val); g_free(val); } /* just write the content of the keys array to the config file */ void keybindings_write_to_file(void) { gchar *configfile = g_build_filename(app->configdir, "keybindings.conf", NULL); gchar *data; GKeyFile *config = g_key_file_new(); g_key_file_load_from_file(config, configfile, 0, NULL); keybindings_foreach(set_keyfile_kb, config); /* write the file */ data = g_key_file_to_data(config, NULL, NULL); utils_write_file(configfile, data); g_free(data); g_free(configfile); g_key_file_free(config); } void keybindings_free(void) { GeanyKeyGroup *group; gsize g; foreach_ptr_array(group, g, keybinding_groups) keybindings_free_group(group); g_ptr_array_free(keybinding_groups, TRUE); } gchar *keybindings_get_label(GeanyKeyBinding *kb) { return utils_str_remove_chars(g_strdup(kb->label), "_"); } static void fill_shortcut_labels_treeview(GtkWidget *tree) { gsize g, i; GeanyKeyBinding *kb; GeanyKeyGroup *group; GtkListStore *store; GtkTreeIter iter; store = gtk_list_store_new(3, G_TYPE_STRING, G_TYPE_STRING, PANGO_TYPE_WEIGHT); foreach_ptr_array(group, g, keybinding_groups) { if (g > 0) { gtk_list_store_append(store, &iter); gtk_list_store_set(store, &iter, -1); } gtk_list_store_append(store, &iter); gtk_list_store_set(store, &iter, 0, group->label, 2, PANGO_WEIGHT_BOLD, -1); foreach_ptr_array(kb, i, group->key_items) { gchar *shortcut, *label; label = keybindings_get_label(kb); shortcut = gtk_accelerator_get_label(kb->key, kb->mods); gtk_list_store_append(store, &iter); gtk_list_store_set(store, &iter, 0, label, 1, shortcut, 2, PANGO_WEIGHT_NORMAL, -1); g_free(shortcut); g_free(label); } } gtk_tree_view_set_model(GTK_TREE_VIEW(tree), GTK_TREE_MODEL(store)); g_object_unref(store); } static GtkWidget *create_dialog(void) { GtkWidget *dialog, *tree, *label, *swin, *vbox; GtkCellRenderer *text_renderer; GtkTreeViewColumn *column; dialog = gtk_dialog_new_with_buttons(_("Keyboard Shortcuts"), GTK_WINDOW(main_widgets.window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_EDIT, GTK_RESPONSE_APPLY, GTK_STOCK_CLOSE, GTK_RESPONSE_CANCEL, NULL); vbox = ui_dialog_vbox_new(GTK_DIALOG(dialog)); gtk_box_set_spacing(GTK_BOX(vbox), 6); gtk_widget_set_name(dialog, "GeanyDialog"); gtk_window_set_default_size(GTK_WINDOW(dialog), -1, GEANY_DEFAULT_DIALOG_HEIGHT); gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_CANCEL); label = gtk_label_new(_("The following keyboard shortcuts are configurable:")); gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); tree = gtk_tree_view_new(); gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(tree), TRUE); gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(tree), FALSE); text_renderer = gtk_cell_renderer_text_new(); /* we can't use "weight-set", see https://bugzilla.gnome.org/show_bug.cgi?id=355214 */ column = gtk_tree_view_column_new_with_attributes( NULL, text_renderer, "text", 0, "weight", 2, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(tree), column); text_renderer = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes(NULL, text_renderer, "text", 1, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(tree), column); fill_shortcut_labels_treeview(tree); swin = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(swin), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(swin), GTK_SHADOW_IN); gtk_container_add(GTK_CONTAINER(swin), tree); gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 6); gtk_box_pack_start(GTK_BOX(vbox), swin, TRUE, TRUE, 0); return dialog; } static void key_dialog_show_prefs(void) { GtkWidget *wid; prefs_show_dialog(); /* select the KB page */ wid = ui_lookup_widget(ui_widgets.prefs_dialog, "frame22"); if (wid != NULL) { GtkNotebook *nb = GTK_NOTEBOOK(ui_lookup_widget(ui_widgets.prefs_dialog, "notebook2")); if (nb != NULL) { gtk_notebook_set_current_page(nb, gtk_notebook_page_num(nb, wid)); } } } void keybindings_dialog_show_prefs_scroll(const gchar *name) { key_dialog_show_prefs(); prefs_kb_search_name(name); } /* non-modal keyboard shortcuts dialog, so user can edit whilst seeing the shortcuts */ static GtkWidget *key_dialog = NULL; static void on_dialog_response(GtkWidget *dialog, gint response, gpointer user_data) { if (response == GTK_RESPONSE_APPLY) { key_dialog_show_prefs(); } gtk_widget_destroy(dialog); key_dialog = NULL; } void keybindings_show_shortcuts(void) { if (key_dialog) gtk_widget_destroy(key_dialog); /* in case the key_dialog is still visible */ key_dialog = create_dialog(); g_signal_connect(key_dialog, "response", G_CALLBACK(on_dialog_response), NULL); gtk_widget_show_all(key_dialog); } static gboolean check_fixed_kb(guint keyval, guint state) { /* check alt-0 to alt-9 for setting current notebook page */ if (state == GDK_MOD1_MASK && keyval >= GDK_KEY_0 && keyval <= GDK_KEY_9) { gint page = keyval - GDK_KEY_0 - 1; gint npages = gtk_notebook_get_n_pages(GTK_NOTEBOOK(main_widgets.notebook)); /* alt-0 is for the rightmost tab */ if (keyval == GDK_KEY_0) page = npages - 1; /* invert the order if tabs are added on the other side */ if (swap_alt_tab_order && ! file_prefs.tab_order_ltr) page = (npages - 1) - page; gtk_notebook_set_current_page(GTK_NOTEBOOK(main_widgets.notebook), page); return TRUE; } /* note: these are now overridden by default with move tab bindings */ if (keyval == GDK_KEY_Page_Up || keyval == GDK_KEY_Page_Down) { /* switch to first or last document */ if (state == (GEANY_PRIMARY_MOD_MASK | GDK_SHIFT_MASK)) { if (keyval == GDK_KEY_Page_Up) gtk_notebook_set_current_page(GTK_NOTEBOOK(main_widgets.notebook), 0); if (keyval == GDK_KEY_Page_Down) gtk_notebook_set_current_page(GTK_NOTEBOOK(main_widgets.notebook), -1); return TRUE; } } return FALSE; } static gboolean check_snippet_completion(GeanyDocument *doc) { GtkWidget *focusw = gtk_window_get_focus(GTK_WINDOW(main_widgets.window)); g_return_val_if_fail(doc, FALSE); /* keybinding only valid when scintilla widget has focus */ if (focusw == GTK_WIDGET(doc->editor->sci)) { ScintillaObject *sci = doc->editor->sci; gint pos = sci_get_current_position(sci); if (editor_prefs.complete_snippets) return editor_complete_snippet(doc->editor, pos); } return FALSE; } /* Transforms a GdkEventKey event into a GdkEventButton event */ static void trigger_button_event(GtkWidget *widget, guint32 event_time) { GdkEventButton *event; gboolean ret; event = g_new0(GdkEventButton, 1); if (GTK_IS_TEXT_VIEW(widget)) event->window = gtk_text_view_get_window(GTK_TEXT_VIEW(widget), GTK_TEXT_WINDOW_TEXT); else event->window = gtk_widget_get_window(widget); event->time = event_time; event->type = GDK_BUTTON_PRESS; event->button = 3; g_signal_emit_by_name(widget, "button-press-event", event, &ret); g_signal_emit_by_name(widget, "button-release-event", event, &ret); g_free(event); } /* Special case for the Menu key and Shift-F10 to show the right-click popup menu for various * widgets. Without this special handling, the notebook tab list of the documents' notebook * would be shown. As a very special case, we differentiate between the Menu key and Shift-F10 * if pressed in the editor widget: the Menu key opens the popup menu, Shift-F10 opens the * notebook tab list. */ static gboolean check_menu_key(GeanyDocument *doc, guint keyval, guint state, guint32 event_time) { g_return_val_if_fail(doc == NULL || doc->is_valid, FALSE); if ((keyval == GDK_KEY_Menu && state == 0) || (keyval == GDK_KEY_F10 && state == GDK_SHIFT_MASK)) { GtkWidget *focusw = gtk_window_get_focus(GTK_WINDOW(main_widgets.window)); if (doc != NULL) { if (focusw == doc->priv->tag_tree) { trigger_button_event(focusw, event_time); return TRUE; } if (focusw == GTK_WIDGET(doc->editor->sci)) { if (keyval == GDK_KEY_Menu) { /* show editor popup menu */ trigger_button_event(focusw, event_time); return TRUE; } else { /* show tab bar menu */ trigger_button_event(main_widgets.notebook, event_time); return TRUE; } } } if (focusw == tv.tree_openfiles || focusw == msgwindow.tree_status || focusw == msgwindow.tree_compiler || focusw == msgwindow.tree_msg || focusw == msgwindow.scribble #ifdef HAVE_VTE || (vte_info.have_vte && focusw == vte_config.vte) #endif ) { trigger_button_event(focusw, event_time); return TRUE; } } return FALSE; } #ifdef HAVE_VTE static gboolean set_sensitive(gpointer widget) { gtk_widget_set_sensitive(GTK_WIDGET(widget), TRUE); return FALSE; } static gboolean check_vte(GdkModifierType state, guint keyval) { guint i; GeanyKeyBinding *kb; GeanyKeyGroup *group; GtkWidget *widget; if (gtk_window_get_focus(GTK_WINDOW(main_widgets.window)) != vte_config.vte) return FALSE; /* let VTE copy/paste override any user keybinding */ if (state == (GEANY_PRIMARY_MOD_MASK | GDK_SHIFT_MASK) && (keyval == GDK_KEY_c || keyval == GDK_KEY_v)) return TRUE; if (! vte_config.enable_bash_keys) return FALSE; /* prevent menubar flickering: */ if (state == GDK_SHIFT_MASK && (keyval >= GDK_KEY_a && keyval <= GDK_KEY_z)) return FALSE; if (state == 0 && (keyval < GDK_KEY_F1 || keyval > GDK_KEY_F35)) /* e.g. backspace */ return FALSE; /* make focus commands override any bash commands */ group = keybindings_get_core_group(GEANY_KEY_GROUP_FOCUS); foreach_ptr_array(kb, i, group->key_items) { if (state == kb->mods && keyval == kb->key) return FALSE; } /* Temporarily disable the menus to prevent conflicting menu accelerators * from overriding the VTE bash shortcuts. * Note: maybe there's a better way of doing this ;-) */ widget = ui_lookup_widget(main_widgets.window, "menubar1"); gtk_widget_set_sensitive(widget, FALSE); g_idle_add_full(G_PRIORITY_HIGH, set_sensitive, widget, NULL); widget = main_widgets.editor_menu; gtk_widget_set_sensitive(widget, FALSE); g_idle_add(set_sensitive, widget); return TRUE; } #endif /* Map the keypad keys to their equivalent functions (taken from ScintillaGTK.cxx) */ static guint key_kp_translate(guint key_in) { switch (key_in) { case GDK_KEY_KP_Down: return GDK_KEY_Down; case GDK_KEY_KP_Up: return GDK_KEY_Up; case GDK_KEY_KP_Left: return GDK_KEY_Left; case GDK_KEY_KP_Right: return GDK_KEY_Right; case GDK_KEY_KP_Home: return GDK_KEY_Home; case GDK_KEY_KP_End: return GDK_KEY_End; case GDK_KEY_KP_Page_Up: return GDK_KEY_Page_Up; case GDK_KEY_KP_Page_Down: return GDK_KEY_Page_Down; case GDK_KEY_KP_Delete: return GDK_KEY_Delete; case GDK_KEY_KP_Insert: return GDK_KEY_Insert; default: return key_in; } } /* Check if event keypress matches keybinding combo */ gboolean keybindings_check_event(GdkEventKey *ev, GeanyKeyBinding *kb) { guint state, keyval; if (ev->keyval == 0) return FALSE; keyval = ev->keyval; state = keybindings_get_modifiers(ev->state); /* hack to get around that CTRL+Shift+r results in GDK_KEY_R not GDK_KEY_r */ if ((ev->state & GDK_SHIFT_MASK) || (ev->state & GDK_LOCK_MASK)) if (keyval >= GDK_KEY_A && keyval <= GDK_KEY_Z) keyval += GDK_KEY_a - GDK_KEY_A; if (keyval >= GDK_KEY_KP_Space && keyval < GDK_KEY_KP_Equal) keyval = key_kp_translate(keyval); return (keyval == kb->key && state == kb->mods); } static gboolean run_kb(GeanyKeyBinding *kb, GeanyKeyGroup *group) { gboolean handled = TRUE; /* call the corresponding handler/callback functions for this shortcut. * Check the individual keybindings first (handler first, callback second) and * group second (again handler first, callback second) */ if (kb->cb_func) handled = kb->cb_func(kb, kb->id, kb->cb_data); else if (kb->callback) kb->callback(kb->id); else if (group->cb_func) handled = group->cb_func(group, kb->id, group->cb_data); else if (group->callback) handled = group->callback(kb->id); else { g_warning("No callback or handler for keybinding %s: %s!", group->name, kb->name); return FALSE; } return handled; } /* central keypress event handler, almost all keypress events go to this function */ static gboolean on_key_press_event(GtkWidget *widget, GdkEventKey *ev, gpointer user_data) { guint state, keyval; gsize g, i; GeanyDocument *doc; GeanyKeyGroup *group; GeanyKeyBinding *kb; gboolean key_press_ret; if (ev->keyval == 0) return FALSE; g_signal_emit_by_name(geany_object, "key-press", ev, &key_press_ret); if (key_press_ret) return TRUE; doc = document_get_current(); if (doc) document_check_disk_status(doc, FALSE); keyval = ev->keyval; state = keybindings_get_modifiers(ev->state); /* hack to get around that CTRL+Shift+r results in GDK_KEY_R not GDK_KEY_r */ if ((ev->state & GDK_SHIFT_MASK) || (ev->state & GDK_LOCK_MASK)) if (keyval >= GDK_KEY_A && keyval <= GDK_KEY_Z) keyval += GDK_KEY_a - GDK_KEY_A; if (keyval >= GDK_KEY_KP_Space && keyval < GDK_KEY_KP_Equal) keyval = key_kp_translate(keyval); /*geany_debug("%d (%d) %d (%d)", keyval, ev->keyval, state, ev->state);*/ /* special cases */ #ifdef HAVE_VTE if (vte_info.have_vte && check_vte(state, keyval)) return FALSE; #endif if (check_menu_key(doc, keyval, state, ev->time)) return TRUE; foreach_ptr_array(group, g, keybinding_groups) { foreach_ptr_array(kb, i, group->key_items) { if (keyval == kb->key && state == kb->mods) { if (run_kb(kb, group)) return TRUE; } } } /* fixed keybindings can be overridden by user bindings, so check them last */ if (check_fixed_kb(keyval, state)) return TRUE; return FALSE; } /* group_id must be a core group, e.g. GEANY_KEY_GROUP_EDITOR * key_id e.g. GEANY_KEYS_EDITOR_CALLTIP */ GeanyKeyBinding *keybindings_lookup_item(guint group_id, guint key_id) { GeanyKeyGroup *group; g_return_val_if_fail(group_id < GEANY_KEY_GROUP_COUNT, NULL); /* can't use this for plugin groups */ group = keybindings_get_core_group(group_id); g_return_val_if_fail(group, NULL); return keybindings_get_item(group, key_id); } /** Mimics a (built-in only) keybinding action. * Example: @code keybindings_send_command(GEANY_KEY_GROUP_FILE, GEANY_KEYS_FILE_OPEN); @endcode * @param group_id @ref GeanyKeyGroupID keybinding group index that contains the @a key_id keybinding. * @param key_id @ref GeanyKeyBindingID keybinding index. */ GEANY_API_SYMBOL void keybindings_send_command(guint group_id, guint key_id) { GeanyKeyBinding *kb; GeanyKeyGroup *group; kb = keybindings_lookup_item(group_id, key_id); group = keybindings_get_core_group(group_id); if (kb && group) run_kb(kb, group); } /* These are the callback functions, either each group or each shortcut has it's * own function. */ static gboolean cb_func_file_action(guint key_id) { switch (key_id) { case GEANY_KEYS_FILE_NEW: document_new_file(NULL, NULL, NULL); cb_func_switch_action(GEANY_KEYS_FOCUS_EDITOR); break; case GEANY_KEYS_FILE_OPEN: on_open1_activate(NULL, NULL); break; case GEANY_KEYS_FILE_OPENSELECTED: on_menu_open_selected_file1_activate(NULL, NULL); break; case GEANY_KEYS_FILE_OPENLASTTAB: { gchar *utf8_filename = g_queue_peek_head(ui_prefs.recent_queue); gchar *locale_filename = utils_get_locale_from_utf8(utf8_filename); document_open_file(locale_filename, FALSE, NULL, NULL); g_free(locale_filename); break; } case GEANY_KEYS_FILE_SAVE: on_save1_activate(NULL, NULL); break; case GEANY_KEYS_FILE_SAVEAS: on_save_as1_activate(NULL, NULL); break; case GEANY_KEYS_FILE_SAVEALL: on_save_all1_activate(NULL, NULL); break; case GEANY_KEYS_FILE_CLOSE: on_close1_activate(NULL, NULL); break; case GEANY_KEYS_FILE_CLOSEALL: on_close_all1_activate(NULL, NULL); break; case GEANY_KEYS_FILE_RELOAD: on_toolbutton_reload_clicked(NULL, NULL); break; case GEANY_KEYS_FILE_RELOAD_ALL: on_reload_all(NULL, NULL); break; case GEANY_KEYS_FILE_PRINT: on_print1_activate(NULL, NULL); break; case GEANY_KEYS_FILE_PROPERTIES: on_file_properties_activate(NULL, NULL); break; case GEANY_KEYS_FILE_QUIT: main_quit(); break; } return TRUE; } static gboolean cb_func_project_action(guint key_id) { switch (key_id) { case GEANY_KEYS_PROJECT_NEW: on_project_new1_activate(NULL, NULL); break; case GEANY_KEYS_PROJECT_NEW_FROM_FOLDER: on_project_new_from_folder1_activate(NULL, NULL); break; case GEANY_KEYS_PROJECT_OPEN: on_project_open1_activate(NULL, NULL); break; case GEANY_KEYS_PROJECT_CLOSE: if (app->project) on_project_close1_activate(NULL, NULL); break; case GEANY_KEYS_PROJECT_PROPERTIES: if (app->project) on_project_properties1_activate(NULL, NULL); break; } return TRUE; } static void cb_func_menu_preferences(guint key_id) { switch (key_id) { case GEANY_KEYS_SETTINGS_PREFERENCES: on_preferences1_activate(NULL, NULL); break; case GEANY_KEYS_SETTINGS_PLUGINPREFERENCES: on_plugin_preferences1_activate(NULL, NULL); break; } } static void cb_func_menu_help(G_GNUC_UNUSED guint key_id) { on_help1_activate(NULL, NULL); } static gboolean cb_func_search_action(guint key_id) { GeanyDocument *doc = document_get_current(); ScintillaObject *sci; /* these work without docs */ switch (key_id) { case GEANY_KEYS_SEARCH_FINDINFILES: on_find_in_files1_activate(NULL, NULL); return TRUE; case GEANY_KEYS_SEARCH_NEXTMESSAGE: on_next_message1_activate(NULL, NULL); return TRUE; case GEANY_KEYS_SEARCH_PREVIOUSMESSAGE: on_previous_message1_activate(NULL, NULL); return TRUE; } if (!doc) return TRUE; sci = doc->editor->sci; switch (key_id) { case GEANY_KEYS_SEARCH_FIND: on_find1_activate(NULL, NULL); break; case GEANY_KEYS_SEARCH_FINDNEXT: on_find_next1_activate(NULL, NULL); break; case GEANY_KEYS_SEARCH_FINDPREVIOUS: on_find_previous1_activate(NULL, NULL); break; case GEANY_KEYS_SEARCH_FINDPREVSEL: on_find_prevsel1_activate(NULL, NULL); break; case GEANY_KEYS_SEARCH_FINDNEXTSEL: on_find_nextsel1_activate(NULL, NULL); break; case GEANY_KEYS_SEARCH_REPLACE: on_replace1_activate(NULL, NULL); break; case GEANY_KEYS_SEARCH_FINDUSAGE: on_find_usage1_activate(NULL, NULL); break; case GEANY_KEYS_SEARCH_FINDDOCUMENTUSAGE: on_find_document_usage1_activate(NULL, NULL); break; case GEANY_KEYS_SEARCH_MARKALL: { gchar *text = NULL; gint pos = sci_get_current_position(sci); /* clear existing search indicators instead if next to cursor */ if (SSM(sci, SCI_INDICATORVALUEAT, GEANY_INDICATOR_SEARCH, pos) || SSM(sci, SCI_INDICATORVALUEAT, GEANY_INDICATOR_SEARCH, MAX(pos - 1, 0))) { text = NULL; } else { text = get_current_word_or_sel(doc, TRUE); } if (sci_has_selection(sci)) search_mark_all(doc, text, GEANY_FIND_MATCHCASE); else search_mark_all(doc, text, GEANY_FIND_MATCHCASE | GEANY_FIND_WHOLEWORD); g_free(text); break; } } return TRUE; } static void cb_func_menu_opencolorchooser(G_GNUC_UNUSED guint key_id) { on_show_color_chooser1_activate(NULL, NULL); } static gboolean cb_func_view_action(guint key_id) { switch (key_id) { case GEANY_KEYS_VIEW_TOGGLEALL: on_menu_toggle_all_additional_widgets1_activate(NULL, NULL); break; case GEANY_KEYS_VIEW_SIDEBAR: on_menu_show_sidebar1_toggled(NULL, NULL); break; case GEANY_KEYS_VIEW_ZOOMIN: on_zoom_in1_activate(NULL, NULL); break; case GEANY_KEYS_VIEW_ZOOMOUT: on_zoom_out1_activate(NULL, NULL); break; case GEANY_KEYS_VIEW_ZOOMRESET: on_normal_size1_activate(NULL, NULL); break; default: break; } return TRUE; } static void cb_func_menu_fullscreen(G_GNUC_UNUSED guint key_id) { GtkCheckMenuItem *c = GTK_CHECK_MENU_ITEM( ui_lookup_widget(main_widgets.window, "menu_fullscreen1")); gtk_check_menu_item_set_active(c, ! gtk_check_menu_item_get_active(c)); } static void cb_func_menu_messagewindow(G_GNUC_UNUSED guint key_id) { GtkCheckMenuItem *c = GTK_CHECK_MENU_ITEM( ui_lookup_widget(main_widgets.window, "menu_show_messages_window1")); gtk_check_menu_item_set_active(c, ! gtk_check_menu_item_get_active(c)); } static gboolean read_current_word(GeanyDocument *doc, gboolean sci_word) { g_return_val_if_fail(DOC_VALID(doc), FALSE); if (sci_word) { editor_find_current_word_sciwc(doc->editor, -1, editor_info.current_word, GEANY_MAX_WORD_LENGTH); } else { editor_find_current_word(doc->editor, -1, editor_info.current_word, GEANY_MAX_WORD_LENGTH, NULL); } return (*editor_info.current_word != 0); } static gboolean check_current_word(GeanyDocument *doc, gboolean sci_word) { if (! read_current_word(doc, sci_word)) { utils_beep(); return FALSE; } return TRUE; } static gchar *get_current_word_or_sel(GeanyDocument *doc, gboolean sci_word) { ScintillaObject *sci = doc->editor->sci; if (sci_has_selection(sci)) return sci_get_selection_contents(sci); return read_current_word(doc, sci_word) ? g_strdup(editor_info.current_word) : NULL; } static void focus_sidebar(void) { if (ui_prefs.sidebar_visible) { gint page_num = gtk_notebook_get_current_page(GTK_NOTEBOOK(main_widgets.sidebar_notebook)); GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(main_widgets.sidebar_notebook), page_num); /* gtk_widget_grab_focus() won't work because of the scrolled window containers */ gtk_widget_child_focus(page, GTK_DIR_TAB_FORWARD); } } static GtkWidget *find_focus_widget(GtkWidget *widget) { GtkWidget *focus = NULL; if (GTK_IS_BIN(widget)) /* optimized simple case */ focus = find_focus_widget(gtk_bin_get_child(GTK_BIN(widget))); else if (GTK_IS_CONTAINER(widget)) { GList *children = gtk_container_get_children(GTK_CONTAINER(widget)); GList *node; for (node = children; node && ! focus; node = node->next) focus = find_focus_widget(node->data); g_list_free(children); } /* Some containers handled above might not have children and be what we want to focus * (e.g. GtkTreeView), so focus that if possible and we don't have anything better */ if (! focus && gtk_widget_get_can_focus(widget)) focus = widget; return focus; } static void focus_msgwindow(void) { if (ui_prefs.msgwindow_visible) { gint page_num = gtk_notebook_get_current_page(GTK_NOTEBOOK(msgwindow.notebook)); GtkWidget *widget = gtk_notebook_get_nth_page(GTK_NOTEBOOK(msgwindow.notebook), page_num); widget = find_focus_widget(widget); if (widget) gtk_widget_grab_focus(widget); else utils_beep(); } } static gboolean cb_func_switch_action(guint key_id) { switch (key_id) { case GEANY_KEYS_FOCUS_EDITOR: { GeanyDocument *doc = document_get_current(); if (doc != NULL) { GtkWidget *sci = GTK_WIDGET(doc->editor->sci); if (gtk_widget_has_focus(sci)) ui_update_statusbar(doc, -1); else gtk_widget_grab_focus(sci); } break; } case GEANY_KEYS_FOCUS_SCRIBBLE: msgwin_switch_tab(MSG_SCRATCH, TRUE); break; case GEANY_KEYS_FOCUS_SEARCHBAR: if (toolbar_prefs.visible) { GtkWidget *search_entry = toolbar_get_widget_child_by_name("SearchEntry"); if (search_entry != NULL) gtk_widget_grab_focus(search_entry); } break; case GEANY_KEYS_FOCUS_SIDEBAR: focus_sidebar(); break; case GEANY_KEYS_FOCUS_VTE: msgwin_switch_tab(MSG_VTE, TRUE); break; case GEANY_KEYS_FOCUS_COMPILER: msgwin_switch_tab(MSG_COMPILER, TRUE); break; case GEANY_KEYS_FOCUS_MESSAGES: msgwin_switch_tab(MSG_MESSAGE, TRUE); break; case GEANY_KEYS_FOCUS_MESSAGE_WINDOW: focus_msgwindow(); break; case GEANY_KEYS_FOCUS_SIDEBAR_DOCUMENT_LIST: sidebar_focus_openfiles_tab(); break; case GEANY_KEYS_FOCUS_SIDEBAR_SYMBOL_LIST: sidebar_focus_symbols_tab(); break; } return TRUE; } static void switch_notebook_page(gint direction) { gint page_count, cur_page, pass; gboolean parent_is_notebook = FALSE; GtkNotebook *notebook; GtkWidget *focusw = gtk_window_get_focus(GTK_WINDOW(main_widgets.window)); /* check whether the current widget is a GtkNotebook or a child of a GtkNotebook */ do { parent_is_notebook = GTK_IS_NOTEBOOK(focusw); } while (! parent_is_notebook && (focusw = gtk_widget_get_parent(focusw)) != NULL); /* if we found a GtkNotebook widget, use it. Otherwise fallback to the documents notebook */ if (parent_is_notebook) notebook = GTK_NOTEBOOK(focusw); else notebook = GTK_NOTEBOOK(main_widgets.notebook); /* now switch pages */ page_count = gtk_notebook_get_n_pages(notebook); cur_page = gtk_notebook_get_current_page(notebook); /* find the next visible page in the wanted direction, but don't loop * indefinitely if no pages are visible */ for (pass = 0; pass < page_count; pass++) { GtkWidget *child; if (direction == GTK_DIR_LEFT) { if (cur_page > 0) cur_page--; else cur_page = page_count - 1; } else if (direction == GTK_DIR_RIGHT) { if (cur_page < page_count - 1) cur_page++; else cur_page = 0; } child = gtk_notebook_get_nth_page (notebook, cur_page); if (gtk_widget_get_visible (child)) { gtk_notebook_set_current_page(notebook, cur_page); break; } } } static void cb_func_switch_tableft(G_GNUC_UNUSED guint key_id) { switch_notebook_page(GTK_DIR_LEFT); } static void cb_func_switch_tabright(G_GNUC_UNUSED guint key_id) { switch_notebook_page(GTK_DIR_RIGHT); } static void cb_func_switch_tablastused(G_GNUC_UNUSED guint key_id) { notebook_switch_tablastused(); } /* move document left/right/first/last */ static void cb_func_move_tab(guint key_id) { GtkWidget *child; GtkNotebook *nb = GTK_NOTEBOOK(main_widgets.notebook); gint cur_page = gtk_notebook_get_current_page(nb); if (cur_page < 0) return; child = gtk_notebook_get_nth_page(nb, cur_page); switch (key_id) { case GEANY_KEYS_NOTEBOOK_MOVETABLEFT: gtk_notebook_reorder_child(nb, child, cur_page - 1); /* notebook wraps around by default */ break; case GEANY_KEYS_NOTEBOOK_MOVETABRIGHT: { gint npage = cur_page + 1; if (npage == gtk_notebook_get_n_pages(nb)) npage = 0; /* wraparound */ gtk_notebook_reorder_child(nb, child, npage); break; } case GEANY_KEYS_NOTEBOOK_MOVETABFIRST: gtk_notebook_reorder_child(nb, child, (file_prefs.tab_order_ltr) ? 0 : -1); break; case GEANY_KEYS_NOTEBOOK_MOVETABLAST: gtk_notebook_reorder_child(nb, child, (file_prefs.tab_order_ltr) ? -1 : 0); break; } return; } static void goto_matching_brace(GeanyDocument *doc) { gint pos, new_pos; gint after_brace; g_return_if_fail(DOC_VALID(doc)); pos = sci_get_current_position(doc->editor->sci); after_brace = pos > 0 && utils_isbrace(sci_get_char_at(doc->editor->sci, pos - 1), TRUE); pos -= after_brace; /* set pos to the brace */ new_pos = sci_find_matching_brace(doc->editor->sci, pos); if (new_pos != -1) { /* set the cursor at/after the brace */ sci_set_current_position(doc->editor->sci, new_pos + (!after_brace), FALSE); editor_display_current_line(doc->editor, 0.5F); } } static gboolean cb_func_clipboard_action(guint key_id) { GtkWidget *focusw = gtk_window_get_focus(GTK_WINDOW(main_widgets.window)); switch (key_id) { case GEANY_KEYS_CLIPBOARD_CUT: on_cut1_activate(NULL, NULL); break; case GEANY_KEYS_CLIPBOARD_COPY: on_copy1_activate(NULL, NULL); break; case GEANY_KEYS_CLIPBOARD_PASTE: on_paste1_activate(NULL, NULL); break; case GEANY_KEYS_CLIPBOARD_COPYLINE: if (IS_SCINTILLA(focusw)) sci_send_command(SCINTILLA(focusw), SCI_LINECOPY); break; case GEANY_KEYS_CLIPBOARD_CUTLINE: if (IS_SCINTILLA(focusw)) sci_send_command(SCINTILLA(focusw), SCI_LINECUT); break; } return TRUE; } static void goto_tag(GeanyDocument *doc, gboolean definition) { gchar *text = get_current_word_or_sel(doc, FALSE); if (text) symbols_goto_tag(text, definition); else utils_beep(); g_free(text); } /* Common function for goto keybindings, useful even when sci doesn't have focus. */ static gboolean cb_func_goto_action(guint key_id) { gint cur_line; GeanyDocument *doc = document_get_current(); if (doc == NULL) return TRUE; cur_line = sci_get_current_line(doc->editor->sci); switch (key_id) { case GEANY_KEYS_GOTO_BACK: navqueue_go_back(); return TRUE; case GEANY_KEYS_GOTO_FORWARD: navqueue_go_forward(); return TRUE; case GEANY_KEYS_GOTO_LINE: { if (toolbar_prefs.visible) { GtkWidget *wid = toolbar_get_widget_child_by_name("GotoEntry"); /* use toolbar item if shown & not in the drop down overflow menu */ if (wid && gtk_widget_get_mapped(wid)) { gtk_widget_grab_focus(wid); return TRUE; } } on_go_to_line_activate(NULL, NULL); return TRUE; } case GEANY_KEYS_GOTO_MATCHINGBRACE: goto_matching_brace(doc); return TRUE; case GEANY_KEYS_GOTO_TOGGLEMARKER: { sci_toggle_marker_at_line(doc->editor->sci, cur_line, 1); return TRUE; } case GEANY_KEYS_GOTO_NEXTMARKER: { gint mline = sci_marker_next(doc->editor->sci, cur_line + 1, 1 << 1, TRUE); if (mline != -1) { sci_set_current_line(doc->editor->sci, mline); editor_display_current_line(doc->editor, 0.5F); } return TRUE; } case GEANY_KEYS_GOTO_PREVIOUSMARKER: { gint mline = sci_marker_previous(doc->editor->sci, cur_line - 1, 1 << 1, TRUE); if (mline != -1) { sci_set_current_line(doc->editor->sci, mline); editor_display_current_line(doc->editor, 0.5F); } return TRUE; } case GEANY_KEYS_GOTO_TAGDEFINITION: goto_tag(doc, TRUE); return TRUE; case GEANY_KEYS_GOTO_TAGDECLARATION: goto_tag(doc, FALSE); return TRUE; } /* only check editor-sensitive keybindings when editor has focus so home,end still * work in other widgets */ if (gtk_window_get_focus(GTK_WINDOW(main_widgets.window)) != GTK_WIDGET(doc->editor->sci)) return FALSE; switch (key_id) { case GEANY_KEYS_GOTO_LINESTART: sci_send_command(doc->editor->sci, editor_prefs.smart_home_key ? SCI_VCHOME : SCI_HOME); break; case GEANY_KEYS_GOTO_LINEEND: sci_send_command(doc->editor->sci, SCI_LINEEND); break; case GEANY_KEYS_GOTO_LINESTARTVISUAL: sci_send_command(doc->editor->sci, editor_prefs.smart_home_key ? SCI_VCHOMEDISPLAY : SCI_HOMEDISPLAY); break; case GEANY_KEYS_GOTO_LINEENDVISUAL: sci_send_command(doc->editor->sci, SCI_LINEENDDISPLAY); break; case GEANY_KEYS_GOTO_PREVWORDPART: sci_send_command(doc->editor->sci, SCI_WORDPARTLEFT); break; case GEANY_KEYS_GOTO_NEXTWORDPART: sci_send_command(doc->editor->sci, SCI_WORDPARTRIGHT); break; } return TRUE; } static void duplicate_lines(GeanyEditor *editor) { if (sci_get_lines_selected(editor->sci) > 1) { /* ignore extra_line because of selecting lines from the line number column */ editor_select_lines(editor, FALSE); sci_selection_duplicate(editor->sci); } else if (sci_has_selection(editor->sci)) sci_selection_duplicate(editor->sci); else sci_line_duplicate(editor->sci); } static void delete_lines(GeanyEditor *editor) { editor_select_lines(editor, TRUE); /* include last line (like cut lines, copy lines do) */ sci_clear(editor->sci); /* (SCI_LINEDELETE only does 1 line) */ } /* common function for editor keybindings, only valid when scintilla has focus. */ static gboolean cb_func_editor_action(guint key_id) { GeanyDocument *doc = document_get_current(); GtkWidget *focusw = gtk_window_get_focus(GTK_WINDOW(main_widgets.window)); /* edit keybindings only valid when scintilla widget has focus */ if (doc == NULL || focusw != GTK_WIDGET(doc->editor->sci)) return FALSE; /* also makes tab work outside editor */ switch (key_id) { case GEANY_KEYS_EDITOR_UNDO: on_undo1_activate(NULL, NULL); break; case GEANY_KEYS_EDITOR_REDO: on_redo1_activate(NULL, NULL); break; case GEANY_KEYS_EDITOR_SCROLLTOLINE: editor_scroll_to_line(doc->editor, -1, 0.5F); break; case GEANY_KEYS_EDITOR_SCROLLLINEUP: sci_send_command(doc->editor->sci, SCI_LINESCROLLUP); break; case GEANY_KEYS_EDITOR_SCROLLLINEDOWN: sci_send_command(doc->editor->sci, SCI_LINESCROLLDOWN); break; case GEANY_KEYS_EDITOR_DUPLICATELINE: duplicate_lines(doc->editor); break; case GEANY_KEYS_EDITOR_SNIPPETNEXTCURSOR: /* allow overloading */ return editor_goto_next_snippet_cursor(doc->editor); case GEANY_KEYS_EDITOR_DELETELINE: delete_lines(doc->editor); break; case GEANY_KEYS_EDITOR_DELETELINETOEND: sci_send_command(doc->editor->sci, SCI_DELLINERIGHT); break; case GEANY_KEYS_EDITOR_DELETELINETOBEGINNING: sci_send_command(doc->editor->sci, SCI_DELLINELEFT); break; case GEANY_KEYS_EDITOR_TRANSPOSELINE: sci_send_command(doc->editor->sci, SCI_LINETRANSPOSE); break; case GEANY_KEYS_EDITOR_AUTOCOMPLETE: editor_start_auto_complete(doc->editor, sci_get_current_position(doc->editor->sci), TRUE); break; case GEANY_KEYS_EDITOR_CALLTIP: editor_show_calltip(doc->editor, -1); break; case GEANY_KEYS_EDITOR_CONTEXTACTION: if (check_current_word(doc, FALSE)) on_context_action1_activate(GTK_MENU_ITEM(ui_lookup_widget(main_widgets.editor_menu, "context_action1")), NULL); break; case GEANY_KEYS_EDITOR_COMPLETESNIPPET: /* allow tab to be overloaded */ return check_snippet_completion(doc); case GEANY_KEYS_EDITOR_SUPPRESSSNIPPETCOMPLETION: { GeanyKeyBinding *kb = keybindings_lookup_item(GEANY_KEY_GROUP_EDITOR, GEANY_KEYS_EDITOR_COMPLETESNIPPET); switch (kb->key) { case GDK_KEY_space: sci_add_text(doc->editor->sci, " "); break; case GDK_KEY_Tab: sci_send_command(doc->editor->sci, SCI_TAB); break; default: break; } break; } case GEANY_KEYS_EDITOR_WORDPARTCOMPLETION: return editor_complete_word_part(doc->editor); case GEANY_KEYS_EDITOR_MOVELINEUP: sci_move_selected_lines_up(doc->editor->sci); break; case GEANY_KEYS_EDITOR_MOVELINEDOWN: sci_move_selected_lines_down(doc->editor->sci); break; } return TRUE; } static void join_lines(GeanyEditor *editor) { gint start, end, i; start = sci_get_line_from_position(editor->sci, sci_get_selection_start(editor->sci)); end = sci_get_line_from_position(editor->sci, sci_get_selection_end(editor->sci)); /* remove spaces surrounding the lines so that these spaces * won't appear within text after joining */ for (i = start; i < end; i++) editor_strip_line_trailing_spaces(editor, i); for (i = start + 1; i <= end; i++) sci_set_line_indentation(editor->sci, i, 0); sci_set_target_start(editor->sci, sci_get_position_from_line(editor->sci, start)); sci_set_target_end(editor->sci, sci_get_position_from_line(editor->sci, end)); sci_lines_join(editor->sci); } static gint get_reflow_column(GeanyEditor *editor) { const GeanyEditorPrefs *eprefs = editor_get_prefs(editor); if (editor->line_breaking) return eprefs->line_break_column; else if (eprefs->long_line_type != 2) return eprefs->long_line_column; else return -1; /* do nothing */ } /* Split the line where the cursor is positioned, on `column`, possibly many times if the line is long. Return the number of lines added because of the splitting. */ static gint split_line(GeanyEditor *editor, gint column) { ScintillaObject *sci = editor->sci; gint start_line = sci_get_current_line(sci); gint line = start_line; while (TRUE) { gint lstart = sci_get_position_from_line(sci, line); gint lend = sci_get_line_end_position(sci, line); gint edge = sci_get_position_from_col(sci, line, column); gboolean found; gint pos; /* don't split on a trailing space of a line */ if (sci_get_char_at(sci, lend - 1) == ' ') lend--; /* detect when the line is short enough and no more splitting is needed */ if (sci_get_col_from_position(sci, lend) < column) break; /* lookup split position */ found = FALSE; for (pos = edge - 1; pos > lstart; pos--) { if (sci_get_char_at(sci, pos) == ' ') { found = TRUE; break; } } if (!found) { for (pos = edge; pos < lend; pos++) { if (sci_get_char_at(sci, pos) == ' ') { found = TRUE; break; } } } /* don't split right before a space */ while (pos + 1 <= lend && sci_get_char_at(sci, pos + 1) == ' ') pos++; if (!found || pos >= lend) break; sci_insert_text(sci, pos + 1, editor_get_eol_char(editor)); line++; } return line - start_line; } static void reflow_lines(GeanyEditor *editor, gint column) { gint start, indent, linescount, i; start = sci_get_line_from_position(editor->sci, sci_get_selection_start(editor->sci)); /* if several lines are selected, join them. */ if (sci_get_lines_selected(editor->sci) > 1) join_lines(editor); /* if this line is short enough, do nothing */ if (column > sci_get_line_end_position(editor->sci, start) - sci_get_position_from_line(editor->sci, start)) { return; } /* * We have to manipulate line indentation so that indentation * of the resulting lines would be consistent. For example, * the result of splitting "[TAB]very long content": * * +-------------+-------------+ * | proper | wrong | * +-------------+-------------+ * | [TAB]very | [TAB]very | * | [TAB]long | long | * | [TAB]content| content | * +-------------+-------------+ */ indent = sci_get_line_indentation(editor->sci, start); sci_set_line_indentation(editor->sci, start, 0); linescount = split_line(editor, column - indent); /* Fix indentation. */ for (i = start; i <= start + linescount; i++) sci_set_line_indentation(editor->sci, i, indent); /* Remove trailing spaces. */ if (editor_prefs.newline_strip || file_prefs.strip_trailing_spaces) { for (i = start; i <= start + linescount; i++) editor_strip_line_trailing_spaces(editor, i); } } /* deselect last newline of selection, if any */ static void sci_deselect_last_newline(ScintillaObject *sci) { gint start, end; start = sci_get_selection_start(sci); end = sci_get_selection_end(sci); if (end > start && sci_get_col_from_position(sci, end) == 0) { end = sci_get_line_end_position(sci, sci_get_line_from_position(sci, end - 1)); sci_set_selection(sci, start, end); } } static void reflow_paragraph(GeanyEditor *editor) { ScintillaObject *sci = editor->sci; gboolean sel; gint column; column = get_reflow_column(editor); if (column == -1) { utils_beep(); return; } sci_start_undo_action(sci); sel = sci_has_selection(sci); if (!sel) editor_select_indent_block(editor); sci_deselect_last_newline(sci); reflow_lines(editor, column); if (!sel) sci_set_anchor(sci, -1); sci_goto_pos(sci, sci_get_line_end_position(sci, sci_get_current_line(sci)), TRUE); sci_end_undo_action(sci); } static void join_paragraph(GeanyEditor *editor) { ScintillaObject *sci = editor->sci; gboolean sel; sci_start_undo_action(sci); sel = sci_has_selection(sci); if (!sel) editor_select_indent_block(editor); sci_deselect_last_newline(sci); join_lines(editor); if (!sel) sci_set_anchor(sci, -1); sci_end_undo_action(sci); } /* common function for format keybindings, only valid when scintilla has focus. */ static gboolean cb_func_format_action(guint key_id) { GeanyDocument *doc = document_get_current(); GtkWidget *focusw = gtk_window_get_focus(GTK_WINDOW(main_widgets.window)); /* keybindings only valid when scintilla widget has focus */ if (doc == NULL || focusw != GTK_WIDGET(doc->editor->sci)) return TRUE; switch (key_id) { case GEANY_KEYS_FORMAT_COMMENTLINETOGGLE: on_menu_toggle_line_commentation1_activate(NULL, NULL); break; case GEANY_KEYS_FORMAT_COMMENTLINE: on_menu_comment_line1_activate(NULL, NULL); break; case GEANY_KEYS_FORMAT_UNCOMMENTLINE: on_menu_uncomment_line1_activate(NULL, NULL); break; case GEANY_KEYS_FORMAT_INCREASEINDENT: on_menu_increase_indent1_activate(NULL, NULL); break; case GEANY_KEYS_FORMAT_DECREASEINDENT: on_menu_decrease_indent1_activate(NULL, NULL); break; case GEANY_KEYS_FORMAT_INCREASEINDENTBYSPACE: editor_indentation_by_one_space(doc->editor, -1, FALSE); break; case GEANY_KEYS_FORMAT_DECREASEINDENTBYSPACE: editor_indentation_by_one_space(doc->editor, -1, TRUE); break; case GEANY_KEYS_FORMAT_AUTOINDENT: editor_smart_line_indentation(doc->editor); break; case GEANY_KEYS_FORMAT_TOGGLECASE: on_toggle_case1_activate(NULL, NULL); break; case GEANY_KEYS_FORMAT_SENDTOCMD1: if (ui_prefs.custom_commands && g_strv_length(ui_prefs.custom_commands) > 0) tools_execute_custom_command(doc, ui_prefs.custom_commands[0]); break; case GEANY_KEYS_FORMAT_SENDTOCMD2: if (ui_prefs.custom_commands && g_strv_length(ui_prefs.custom_commands) > 1) tools_execute_custom_command(doc, ui_prefs.custom_commands[1]); break; case GEANY_KEYS_FORMAT_SENDTOCMD3: if (ui_prefs.custom_commands && g_strv_length(ui_prefs.custom_commands) > 2) tools_execute_custom_command(doc, ui_prefs.custom_commands[2]); break; case GEANY_KEYS_FORMAT_SENDTOCMD4: if (ui_prefs.custom_commands && g_strv_length(ui_prefs.custom_commands) > 3) tools_execute_custom_command(doc, ui_prefs.custom_commands[3]); break; case GEANY_KEYS_FORMAT_SENDTOCMD5: if (ui_prefs.custom_commands && g_strv_length(ui_prefs.custom_commands) > 4) tools_execute_custom_command(doc, ui_prefs.custom_commands[4]); break; case GEANY_KEYS_FORMAT_SENDTOCMD6: if (ui_prefs.custom_commands && g_strv_length(ui_prefs.custom_commands) > 5) tools_execute_custom_command(doc, ui_prefs.custom_commands[5]); break; case GEANY_KEYS_FORMAT_SENDTOCMD7: if (ui_prefs.custom_commands && g_strv_length(ui_prefs.custom_commands) > 6) tools_execute_custom_command(doc, ui_prefs.custom_commands[6]); break; case GEANY_KEYS_FORMAT_SENDTOCMD8: if (ui_prefs.custom_commands && g_strv_length(ui_prefs.custom_commands) > 7) tools_execute_custom_command(doc, ui_prefs.custom_commands[7]); break; case GEANY_KEYS_FORMAT_SENDTOCMD9: if (ui_prefs.custom_commands && g_strv_length(ui_prefs.custom_commands) > 8) tools_execute_custom_command(doc, ui_prefs.custom_commands[8]); break; case GEANY_KEYS_FORMAT_SENDTOVTE: on_send_selection_to_vte1_activate(NULL, NULL); break; case GEANY_KEYS_FORMAT_REFLOWPARAGRAPH: reflow_paragraph(doc->editor); break; case GEANY_KEYS_FORMAT_JOINLINES: join_paragraph(doc->editor); break; } return TRUE; } /* common function for select keybindings, valid for scintilla and/or gtk_editable objects. */ static gboolean cb_func_select_action(guint key_id) { GeanyDocument *doc = document_get_current(); GtkWidget *focusw = gtk_window_get_focus(GTK_WINDOW(main_widgets.window)); switch (key_id) { case GEANY_KEYS_SELECT_ALL: on_menu_select_all1_activate(NULL, NULL); break; case GEANY_KEYS_SELECT_WORD: if (doc != NULL) editor_select_word(doc->editor); break; case GEANY_KEYS_SELECT_LINE: if (doc != NULL) editor_select_lines(doc->editor, FALSE); break; case GEANY_KEYS_SELECT_PARAGRAPH: if (doc != NULL) editor_select_paragraph(doc->editor); break; case GEANY_KEYS_SELECT_WORDPARTLEFT: if (IS_SCINTILLA(focusw)) sci_send_command(SCINTILLA(focusw), SCI_WORDPARTLEFTEXTEND); break; case GEANY_KEYS_SELECT_WORDPARTRIGHT: if (IS_SCINTILLA(focusw)) sci_send_command(SCINTILLA(focusw), SCI_WORDPARTRIGHTEXTEND); break; } return TRUE; } static gboolean cb_func_document_action(guint key_id) { GeanyDocument *doc = document_get_current(); if (doc == NULL) return TRUE; switch (key_id) { case GEANY_KEYS_DOCUMENT_REPLACETABS: on_replace_tabs_activate(NULL, NULL); break; case GEANY_KEYS_DOCUMENT_REPLACESPACES: on_replace_spaces_activate(NULL, NULL); break; case GEANY_KEYS_DOCUMENT_LINEBREAK: on_line_breaking1_activate(NULL, NULL); ui_document_show_hide(doc); break; case GEANY_KEYS_DOCUMENT_LINEWRAP: on_line_wrapping1_toggled(NULL, NULL); ui_document_show_hide(doc); break; case GEANY_KEYS_DOCUMENT_CLONE: document_clone(doc); break; case GEANY_KEYS_DOCUMENT_RELOADTAGLIST: document_update_tags(doc); break; case GEANY_KEYS_DOCUMENT_FOLDALL: editor_fold_all(doc->editor); break; case GEANY_KEYS_DOCUMENT_UNFOLDALL: editor_unfold_all(doc->editor); break; case GEANY_KEYS_DOCUMENT_TOGGLEFOLD: if (editor_prefs.folding) { gint line = sci_get_current_line(doc->editor->sci); editor_toggle_fold(doc->editor, line, 0); } break; case GEANY_KEYS_DOCUMENT_REMOVE_MARKERS: on_remove_markers1_activate(NULL, NULL); break; case GEANY_KEYS_DOCUMENT_REMOVE_ERROR_INDICATORS: on_menu_remove_indicators1_activate(NULL, NULL); break; case GEANY_KEYS_DOCUMENT_REMOVE_MARKERS_INDICATORS: on_remove_markers1_activate(NULL, NULL); on_menu_remove_indicators1_activate(NULL, NULL); break; case GEANY_KEYS_DOCUMENT_STRIPTRAILINGSPACES: editor_strip_trailing_spaces(doc->editor, FALSE); break; } return TRUE; } static void insert_line_after(GeanyEditor *editor) { ScintillaObject *sci = editor->sci; sci_send_command(sci, SCI_LINEEND); sci_send_command(sci, SCI_NEWLINE); } static void insert_line_before(GeanyEditor *editor) { ScintillaObject *sci = editor->sci; gint line = sci_get_current_line(sci); gint indentpos = sci_get_line_indent_position(sci, line); sci_set_current_position(sci, indentpos, TRUE); sci_send_command(sci, SCI_NEWLINE); sci_send_command(sci, SCI_LINEUP); } /* common function for insert keybindings, only valid when scintilla has focus. */ static gboolean cb_func_insert_action(guint key_id) { GeanyDocument *doc = document_get_current(); GtkWidget *focusw = gtk_window_get_focus(GTK_WINDOW(main_widgets.window)); /* keybindings only valid when scintilla widget has focus */ if (doc == NULL || focusw != GTK_WIDGET(doc->editor->sci)) return TRUE; switch (key_id) { case GEANY_KEYS_INSERT_ALTWHITESPACE: editor_insert_alternative_whitespace(doc->editor); break; case GEANY_KEYS_INSERT_DATE: gtk_menu_item_activate(GTK_MENU_ITEM( ui_lookup_widget(main_widgets.window, "insert_date_custom1"))); break; case GEANY_KEYS_INSERT_LINEAFTER: insert_line_after(doc->editor); break; case GEANY_KEYS_INSERT_LINEBEFORE: insert_line_before(doc->editor); break; } return TRUE; } /* update key combination */ void keybindings_update_combo(GeanyKeyBinding *kb, guint key, GdkModifierType mods) { GtkWidget *widget = kb->menu_item; if (widget && kb->key) gtk_widget_remove_accelerator(widget, kb_accel_group, kb->key, kb->mods); kb->key = key; kb->mods = mods; if (widget && kb->key) gtk_widget_add_accelerator(widget, "activate", kb_accel_group, kb->key, kb->mods, GTK_ACCEL_VISIBLE); } /* used for plugins, can be called repeatedly. */ GeanyKeyGroup *keybindings_set_group(GeanyKeyGroup *group, const gchar *section_name, const gchar *label, gsize count, GeanyKeyGroupCallback callback) { g_return_val_if_fail(section_name, NULL); g_return_val_if_fail(count, NULL); /* prevent conflict with core bindings */ g_return_val_if_fail(!g_str_equal(section_name, keybindings_keyfile_group_name), NULL); if (!group) { group = g_new0(GeanyKeyGroup, 1); add_kb_group(group, section_name, label, callback, TRUE); } /* Calls free_key_binding() for individual entries for plugins - has to be * called before g_free(group->plugin_keys) */ g_ptr_array_set_size(group->key_items, 0); g_free(group->plugin_keys); group->plugin_keys = g_new0(GeanyKeyBinding, count); group->plugin_key_count = count; return group; } void keybindings_free_group(GeanyKeyGroup *group) { g_ptr_array_remove_fast(keybinding_groups, group); } geany-2.0/src/sidebar.c0000644000175000017500000014166314514252267011766 00000000000000/* * sidebar.c - this file is part of Geany, a fast and lightweight IDE * * Copyright 2005 The Geany contributors * * This program 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; either version 2 of the License, or * (at your option) any later version. * * This program 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /* * Sidebar related code for the Symbol list and Open files GtkTreeViews. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include "sidebar.h" #include "app.h" #include "callbacks.h" /* FIXME: for ignore_callback */ #include "documentprivate.h" #include "filetypesprivate.h" #include "geanyobject.h" #include "keyfile.h" #include "navqueue.h" #include "stash.h" #include "support.h" #include "symbols.h" #include "ui_utils.h" #include "utils.h" #include "keybindings.h" #include #include SidebarTreeviews tv = {NULL, NULL, NULL}; /* while typeahead searching, editor should not get focus */ static gboolean may_steal_focus = FALSE; static struct { GtkWidget *close; GtkWidget *save; GtkWidget *reload; GtkWidget *show_paths[OPENFILES_PATHS_COUNT]; GtkWidget *find_in_files; GtkWidget *expand_all; GtkWidget *collapse_all; } doc_items; enum { TREEVIEW_SYMBOL = 0, TREEVIEW_OPENFILES }; enum { OPENFILES_ACTION_REMOVE = 0, OPENFILES_ACTION_SAVE, OPENFILES_ACTION_RELOAD }; static GtkTreeStore *store_openfiles; static GtkWidget *openfiles_popup_menu; static GtkWidget *tag_window; /* scrolled window that holds the symbol list GtkTreeView */ /* callback prototypes */ static void on_openfiles_document_action(GtkMenuItem *menuitem, gpointer user_data); static gboolean sidebar_button_press_cb(GtkWidget *widget, GdkEventButton *event, gpointer user_data); static gboolean sidebar_key_press_cb(GtkWidget *widget, GdkEventKey *event, gpointer user_data); static void on_list_document_activate(GtkCheckMenuItem *item, gpointer user_data); static void on_list_symbol_activate(GtkCheckMenuItem *item, gpointer user_data); static void documents_menu_update(GtkTreeSelection *selection); static void sidebar_tabs_show_hide(GtkNotebook *notebook, GtkWidget *child, guint page_num, gpointer data); /* the prepare_* functions are document-related, but I think they fit better here than in document.c */ static void prepare_taglist(GtkWidget *tree, GtkTreeStore *store) { GtkCellRenderer *text_renderer, *icon_renderer; GtkTreeViewColumn *column; GtkTreeSelection *selection; text_renderer = gtk_cell_renderer_text_new(); icon_renderer = gtk_cell_renderer_pixbuf_new(); column = gtk_tree_view_column_new(); gtk_tree_view_column_pack_start(column, icon_renderer, FALSE); gtk_tree_view_column_set_attributes(column, icon_renderer, "pixbuf", SYMBOLS_COLUMN_ICON, NULL); g_object_set(icon_renderer, "xalign", 0.0, NULL); gtk_tree_view_column_pack_start(column, text_renderer, TRUE); gtk_tree_view_column_set_attributes(column, text_renderer, "text", SYMBOLS_COLUMN_NAME, NULL); g_object_set(text_renderer, "yalign", 0.5, NULL); gtk_tree_view_column_set_title(column, _("Symbols")); gtk_tree_view_append_column(GTK_TREE_VIEW(tree), column); gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(tree), FALSE); ui_widget_modify_font_from_string(tree, interface_prefs.tagbar_font); gtk_tree_view_set_model(GTK_TREE_VIEW(tree), GTK_TREE_MODEL(store)); g_object_unref(store); g_signal_connect(tree, "button-press-event", G_CALLBACK(sidebar_button_press_cb), NULL); g_signal_connect(tree, "key-press-event", G_CALLBACK(sidebar_key_press_cb), NULL); gtk_tree_view_set_show_expanders(GTK_TREE_VIEW(tree), interface_prefs.show_symbol_list_expanders); if (! interface_prefs.show_symbol_list_expanders) gtk_tree_view_set_level_indentation(GTK_TREE_VIEW(tree), 10); /* Tooltips */ ui_tree_view_set_tooltip_text_column(GTK_TREE_VIEW(tree), SYMBOLS_COLUMN_TOOLTIP); /* selection handling */ selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree)); gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE); /* callback for changed selection not necessary, will be handled by button-press-event */ } static gboolean on_default_tag_tree_button_press_event(GtkWidget *widget, GdkEventButton *event, gpointer user_data) { if (event->button == 3) { gtk_menu_popup_at_pointer(GTK_MENU(tv.popup_taglist), (GdkEvent *) event); return TRUE; } return FALSE; } static void create_default_tag_tree(void) { GtkScrolledWindow *scrolled_window = GTK_SCROLLED_WINDOW(tag_window); GtkWidget *label; /* default_tag_tree is a GtkViewPort with a GtkLabel inside it */ tv.default_tag_tree = gtk_viewport_new( gtk_scrolled_window_get_hadjustment(scrolled_window), gtk_scrolled_window_get_vadjustment(scrolled_window)); gtk_viewport_set_shadow_type(GTK_VIEWPORT(tv.default_tag_tree), GTK_SHADOW_NONE); label = gtk_label_new(_("No symbols found")); gtk_misc_set_alignment(GTK_MISC(label), 0.1f, 0.01f); gtk_container_add(GTK_CONTAINER(tv.default_tag_tree), label); gtk_widget_show_all(tv.default_tag_tree); g_signal_connect(tv.default_tag_tree, "button-press-event", G_CALLBACK(on_default_tag_tree_button_press_event), NULL); g_object_ref((gpointer)tv.default_tag_tree); /* to hold it after removing */ } /* update = rescan the tags for doc->filename */ void sidebar_update_tag_list(GeanyDocument *doc, gboolean update) { GtkWidget *child = gtk_bin_get_child(GTK_BIN(tag_window)); g_return_if_fail(doc == NULL || doc->is_valid); if (update && doc != NULL) doc->priv->tag_tree_dirty = TRUE; if (gtk_notebook_get_current_page(GTK_NOTEBOOK(main_widgets.sidebar_notebook)) != TREEVIEW_SYMBOL) return; /* don't bother updating symbol tree if we don't see it */ /* changes the tree view to the given one, trying not to do useless changes */ #define CHANGE_TREE(new_child) \ G_STMT_START { \ /* only change the tag tree if it's actually not the same (to avoid flickering) and if \ * it's the one of the current document (to avoid problems when e.g. reloading \ * configuration files */ \ if (child != new_child && doc == document_get_current()) \ { \ if (child) \ gtk_container_remove(GTK_CONTAINER(tag_window), child); \ gtk_container_add(GTK_CONTAINER(tag_window), new_child); \ } \ } G_STMT_END if (tv.default_tag_tree == NULL) create_default_tag_tree(); /* show default empty tag tree if there are no tags */ if (doc == NULL || doc->file_type == NULL || ! filetype_has_tags(doc->file_type)) { CHANGE_TREE(tv.default_tag_tree); return; } if (doc->priv->tag_tree_dirty) { /* updating the tag list in the left tag window */ if (doc->priv->tag_tree == NULL) { doc->priv->tag_store = gtk_tree_store_new( SYMBOLS_N_COLUMNS, GDK_TYPE_PIXBUF, G_TYPE_STRING, TM_TYPE_TAG, G_TYPE_STRING); doc->priv->tag_tree = gtk_tree_view_new(); prepare_taglist(doc->priv->tag_tree, doc->priv->tag_store); gtk_widget_show(doc->priv->tag_tree); g_object_ref((gpointer)doc->priv->tag_tree); /* to hold it after removing */ } doc->has_tags = symbols_recreate_tag_list(doc, SYMBOLS_SORT_USE_PREVIOUS); doc->priv->tag_tree_dirty = FALSE; } if (doc->has_tags) { CHANGE_TREE(doc->priv->tag_tree); } else { CHANGE_TREE(tv.default_tag_tree); } #undef CHANGE_TREE } /* cleverly sorts documents by their short name */ static gint documents_sort_func(GtkTreeModel *model, GtkTreeIter *iter_a, GtkTreeIter *iter_b, gpointer data) { gchar *name_a, *name_b; GeanyDocument *doc_a, *doc_b; gint cmp; gtk_tree_model_get(model, iter_a, DOCUMENTS_SHORTNAME, &name_a, DOCUMENTS_DOCUMENT, &doc_a, -1); gtk_tree_model_get(model, iter_b, DOCUMENTS_SHORTNAME, &name_b, DOCUMENTS_DOCUMENT, &doc_b, -1); /* sort dirs after files (within a directory node) */ if (!doc_a && doc_b) cmp = 1; else if (doc_a && !doc_b) cmp = -1; else { gchar *key_a, *key_b; /* g_utf8_collate_key_for_filename() seems to ignore ~. As a result, ~/dev <=> /data * compares as /dev > /data while ~/dev <=> /etc compares as /dev < /etc. Thus, for sorting * purposes, treat leading ~ as . which is documented to be special-cased to sort before * anything else. The side effect, that documents under ~ are always first is actually * welcome. */ name_a[0] = name_a[0] == '~' ? '.' : name_a[0]; name_b[0] = name_b[0] == '~' ? '.' : name_b[0]; key_a = g_utf8_collate_key_for_filename(name_a, -1); key_b = g_utf8_collate_key_for_filename(name_b, -1); cmp = strcmp(key_a, key_b); g_free(key_b); g_free(key_a); } g_free(name_b); g_free(name_a); return cmp; } GEANY_EXPORT_SYMBOL GtkTreeStore *sidebar_create_store_openfiles(void) { GtkTreeSortable *sortable; GtkTreeStore *store; /* store the icon and the short filename to show, and the index as reference, * the colour (black/red/green) and the full name for the tooltip */ store = gtk_tree_store_new(6, G_TYPE_ICON, G_TYPE_STRING, G_TYPE_POINTER, GDK_TYPE_COLOR, G_TYPE_STRING, G_TYPE_BOOLEAN); /* sort opened filenames in the store_openfiles treeview */ sortable = GTK_TREE_SORTABLE(GTK_TREE_MODEL(store)); gtk_tree_sortable_set_sort_func(sortable, DOCUMENTS_SHORTNAME, documents_sort_func, NULL, NULL); gtk_tree_sortable_set_sort_column_id(sortable, DOCUMENTS_SHORTNAME, GTK_SORT_ASCENDING); store_openfiles = store; return store; } static void store_fold_recurse(GtkTreeView *view, GtkTreeIter *iter, GtkTreeModel *model) { GeanyDocument *doc; gboolean fold, valid; GtkTreePath *path; GtkTreeIter child_iter; gtk_tree_model_get(model, iter, DOCUMENTS_DOCUMENT, &doc, -1); if (doc) /* document rows are not foldable */ return; path = gtk_tree_model_get_path(model, iter); fold = !gtk_tree_view_row_expanded(view, path); gtk_tree_store_set(GTK_TREE_STORE(model), iter, DOCUMENTS_FOLD, fold, -1); gtk_tree_path_free(path); /* After storing the fold state for *this* row, recursively do the same for its children. * We need do do this only for expanded children because all children of folded rows are * folded as well. */ if (fold) return; valid = gtk_tree_model_iter_children(model, &child_iter, iter); while (valid) { store_fold_recurse(view, &child_iter, model); valid = gtk_tree_model_iter_next(model, &child_iter); } } static gboolean on_row_expand(GtkTreeView *view, GtkTreeIter *iter, GtkTreePath *path, gpointer user_data) { GtkTreeModel *model; model = gtk_tree_view_get_model(view); gtk_tree_store_set(GTK_TREE_STORE(model), iter, DOCUMENTS_FOLD, FALSE, -1); return FALSE; } static gboolean on_row_collapse(GtkTreeView *view, GtkTreeIter *iter, GtkTreePath *path, gpointer user_data) { GtkTreeModel *model; GtkTreeIter child_iter; gboolean valid; model = gtk_tree_view_get_model(view); gtk_tree_store_set(GTK_TREE_STORE(model), iter, DOCUMENTS_FOLD, TRUE, -1); valid = gtk_tree_model_iter_children(model, &child_iter, iter); while (valid) { store_fold_recurse(view, &child_iter, model); valid = gtk_tree_model_iter_next(model, &child_iter); } return FALSE; } static void on_row_expanded(GtkTreeView *view, GtkTreeIter *iter, GtkTreePath *path_, gpointer user_data) { GtkTreeIter child_iter; GtkTreeModel *model; GtkTreePath *path; gboolean valid; GeanyDocument *doc; model = gtk_tree_view_get_model(view); valid = gtk_tree_model_iter_children(model, &child_iter, iter); while (valid) { gboolean fold; gtk_tree_model_get(model, &child_iter, DOCUMENTS_DOCUMENT, &doc, DOCUMENTS_FOLD, &fold, -1); path = gtk_tree_model_get_path(model, &child_iter); if (!doc && !fold) gtk_tree_view_expand_row(view, path, FALSE); valid = gtk_tree_model_iter_next(model, &child_iter); gtk_tree_path_free(path); } } /* does some preparing things to the open files list widget */ static void prepare_openfiles(void) { GtkCellRenderer *icon_renderer; GtkCellRenderer *text_renderer; GtkTreeViewColumn *column; GtkTreeSelection *selection; tv.tree_openfiles = ui_lookup_widget(main_widgets.window, "treeview6"); sidebar_create_store_openfiles(); gtk_tree_view_set_model(GTK_TREE_VIEW(tv.tree_openfiles), GTK_TREE_MODEL(store_openfiles)); /* These two implement "remember fold state of rows when their parents are folded". Normally * GTK does not remember the fold state and can only expand all or no children when * expanding a row. Maybe this can be useful for other tree views as well? */ g_signal_connect_after(GTK_TREE_VIEW(tv.tree_openfiles), "test-expand-row", G_CALLBACK(on_row_expand), NULL); g_signal_connect_after(GTK_TREE_VIEW(tv.tree_openfiles), "test-collapse-row", G_CALLBACK(on_row_collapse), NULL); g_signal_connect_after(GTK_TREE_VIEW(tv.tree_openfiles), "row-expanded", G_CALLBACK(on_row_expanded), NULL); /* set policy settings for the scolledwindow around the treeview again, because glade * doesn't keep the settings */ gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW(ui_lookup_widget(main_widgets.window, "scrolledwindow7")), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); icon_renderer = gtk_cell_renderer_pixbuf_new(); g_object_set(icon_renderer, "stock-size", GTK_ICON_SIZE_MENU, NULL); text_renderer = gtk_cell_renderer_text_new(); g_object_set(text_renderer, "ellipsize", PANGO_ELLIPSIZE_MIDDLE, NULL); column = gtk_tree_view_column_new(); gtk_tree_view_column_pack_start(column, icon_renderer, FALSE); gtk_tree_view_column_set_attributes(column, icon_renderer, "gicon", DOCUMENTS_ICON, NULL); gtk_tree_view_column_pack_start(column, text_renderer, TRUE); gtk_tree_view_column_set_attributes(column, text_renderer, "text", DOCUMENTS_SHORTNAME, "foreground-gdk", DOCUMENTS_COLOR, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(tv.tree_openfiles), column); gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(tv.tree_openfiles), FALSE); gtk_tree_view_set_search_column(GTK_TREE_VIEW(tv.tree_openfiles), DOCUMENTS_SHORTNAME); ui_widget_modify_font_from_string(tv.tree_openfiles, interface_prefs.tagbar_font); /* tooltips */ ui_tree_view_set_tooltip_text_column(GTK_TREE_VIEW(tv.tree_openfiles), DOCUMENTS_FILENAME); /* selection handling */ selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tv.tree_openfiles)); gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE); g_object_unref(store_openfiles); g_signal_connect(GTK_TREE_VIEW(tv.tree_openfiles), "button-press-event", G_CALLBACK(sidebar_button_press_cb), NULL); g_signal_connect(GTK_TREE_VIEW(tv.tree_openfiles), "key-press-event", G_CALLBACK(sidebar_key_press_cb), NULL); } static gboolean utils_filename_has_prefix(const gchar *str, const gchar *prefix) { gchar *head = g_strndup(str, strlen(prefix)); gboolean ret = utils_filenamecmp(head, prefix) == 0; g_free(head); return ret; } static gchar *get_project_folder(const gchar *path) { gchar *project_base_path; gchar *dirname = NULL; const gchar *rest; /* replace the project base path with the project name */ project_base_path = project_get_base_path(); if (project_base_path != NULL) { gsize len = strlen(project_base_path); /* remove trailing separator so we can match base path exactly */ if (project_base_path[len-1] == G_DIR_SEPARATOR) project_base_path[--len] = '\0'; /* check whether the dir name matches or uses the project base path */ if (utils_filename_has_prefix(path, project_base_path)) { rest = path + len; if (*rest == G_DIR_SEPARATOR || *rest == '\0') { dirname = g_strdup_printf("%s%s", app->project->name, rest); } } g_free(project_base_path); } return dirname; } static gchar *get_doc_folder(const gchar *path) { gchar *dirname = get_project_folder(path); const gchar *rest; if (dirname == NULL) { const gchar *home_dir = g_get_home_dir(); gchar *tmp_dirname = g_strdup(path); dirname = tmp_dirname; /* If matches home dir, replace with tilde */ if (!EMPTY(home_dir) && utils_filename_has_prefix(dirname, home_dir)) { rest = dirname + strlen(home_dir); if (*rest == G_DIR_SEPARATOR || *rest == '\0') { dirname = g_strdup_printf("~%s", rest); g_free(tmp_dirname); } } } return dirname; } static gchar *parent_dir_name(GtkTreeStore *tree, GtkTreeIter *parent, const gchar *path) { gsize parent_len = 0; gchar *dirname; gchar *pathname = NULL; if (parent) { gchar *parent_dir; GtkTreeModel *model = GTK_TREE_MODEL(tree); gtk_tree_model_get(model, parent, DOCUMENTS_FILENAME, &parent_dir, -1); if (parent_dir) { pathname = get_doc_folder(parent_dir); parent_len = strlen(pathname) + 1; g_free(parent_dir); } } dirname = get_doc_folder(path); if (parent_len) { gsize len; dirname = get_doc_folder(path); len = strlen(dirname); /* Maybe parent is /home but dirname is ~ (after substitution from /home/user) */ if (pathname[0] == dirname[0]) memmove(dirname, dirname + parent_len, len - parent_len + 1); } g_free(pathname); return dirname; } static void tree_copy_node(GtkTreeStore *tree, GtkTreeIter *new_node, GtkTreeIter *node, GtkTreeIter *parent_new) { GIcon *icon; gchar *filename; gchar *shortname; GdkColor *color; GeanyDocument *doc; GtkTreeModel *model = GTK_TREE_MODEL(tree); gboolean fold; gtk_tree_store_append(tree, new_node, parent_new); gtk_tree_model_get(model, node, DOCUMENTS_ICON, &icon, DOCUMENTS_SHORTNAME, &shortname, DOCUMENTS_DOCUMENT, &doc, DOCUMENTS_COLOR, &color, DOCUMENTS_FILENAME, &filename, DOCUMENTS_FOLD, &fold, -1); if (doc) doc->priv->iter = *new_node; else SETPTR(shortname, parent_dir_name(tree, parent_new, filename)); gtk_tree_store_set(tree, new_node, DOCUMENTS_ICON, icon, DOCUMENTS_SHORTNAME, shortname, DOCUMENTS_DOCUMENT, doc, DOCUMENTS_COLOR, color, DOCUMENTS_FILENAME, filename, DOCUMENTS_FOLD, fold, -1); g_free(filename); g_free(shortname); if (color) gdk_color_free(color); } /* Helper that implements the recursive part of tree_reparent() */ static void tree_reparent_recurse(GtkTreeStore *tree, GtkTreeIter *node, GtkTreeIter *parent_new, GtkTreeIter *new_node) { GtkTreeModel *model = GTK_TREE_MODEL(tree); GtkTreeIter child; /* Start by copying the node itself. It becomes parent_new for the children to be copied. */ tree_copy_node(tree, new_node, node, parent_new); if (gtk_tree_model_iter_nth_child(model, &child, node, 0)) { do { GtkTreeIter new_child; tree_reparent_recurse(tree, &child, new_node, &new_child); } while (gtk_tree_model_iter_next(model, &child)); } } /* * Copy node and all of its children to a new parent, and then remove the old node. * * It is done by reparenting the node itself to the new parent, creating a copy of it, * and then recursively reparenting all children to the copy of the node. * * Finally, the new location will be written back to node so it's readily available, * e.g. to unfold it. * */ static void tree_reparent(GtkTreeStore *tree, GtkTreeIter *node, GtkTreeIter *parent_new) { GtkTreeIter new_node; tree_reparent_recurse(tree, node, parent_new, &new_node); gtk_tree_store_remove(tree, node); *node = new_node; } static void tree_add_new_dir(GtkTreeStore *tree, GtkTreeIter *child, GtkTreeIter *parent, const gchar *file) { static GIcon *dir_icon = NULL; gchar *dirname = parent_dir_name(tree, parent, file); if (!dir_icon) dir_icon = ui_get_mime_icon("inode/directory"); gtk_tree_store_append(tree, child, parent); gtk_tree_store_set(tree, child, DOCUMENTS_ICON, dir_icon, DOCUMENTS_FILENAME, file, DOCUMENTS_SHORTNAME, dirname, DOCUMENTS_FOLD, TRUE, /* GTK inserts folded by default, caller may expand */ -1); g_free(dirname); } /* * Returns the position of dir delimiter where paths don't match * */ static guint pathcmp(const gchar *s1, const gchar *s2) { guint i = 0; gchar *a; gchar *b; g_return_val_if_fail(s1 != NULL, 0); g_return_val_if_fail(s2 != NULL, 0); #ifdef G_OS_WIN32 a = utils_utf8_strdown(s1); if (NULL == a) return 0; b = utils_utf8_strdown(s2); if (NULL == b) { g_free(a); return 0; } #else a = (gchar*)s1; b = (gchar*)s2; #endif while (a[i] && b[i] && a[i] == b[i]) i++; if (a[i] == '\0' && b[i] == '\0') return i; /* strings are equal: a/b/c == a/b/c */ if ((a[i] == '\0' && b[i] == G_DIR_SEPARATOR) || (b[i] == '\0' && a[i] == G_DIR_SEPARATOR)) return i; /* subdir case: a/b/c == a/b */ while (i > 0 && (a[i] != G_DIR_SEPARATOR || b[i] != G_DIR_SEPARATOR)) i--; /* last slash: a/b/boo == a/b/bar */ #ifdef G_OS_WIN32 g_free(a); g_free(b); #endif return i; } typedef struct TreeForeachData { gchar *needle; gsize best_len; gsize needle_len; GtkTreeIter best_iter; enum { TREE_CASE_NONE, TREE_CASE_EQUALS, TREE_CASE_CHILD_OF, TREE_CASE_PARENT_OF, TREE_CASE_HAVE_SAME_PARENT } best_case; } TreeForeachData; static gboolean tree_foreach_callback(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer user_data) { gchar *name; gchar *dirname; guint diff; gsize name_len; GeanyDocument *doc; TreeForeachData *data = (TreeForeachData*) user_data; gtk_tree_model_get(model, iter, DOCUMENTS_FILENAME, &name, DOCUMENTS_DOCUMENT, &doc, -1); if (doc) /* skip documents */ goto finally; dirname = get_doc_folder(name); if (dirname) SETPTR(name, dirname); diff = pathcmp(name, data->needle); name_len = strlen(name); if (diff == 0) goto finally; if (data->best_len < diff) { gint best_case; gboolean tree = interface_prefs.openfiles_path_mode == OPENFILES_PATHS_TREE; /* there are four cases */ /* first case: exact match. File is from already opened dir */ if (name_len == diff && data->needle_len == name_len) best_case = TREE_CASE_EQUALS; /* second case: split current dir. File is from deeper level */ else if (name_len == diff && tree) best_case = TREE_CASE_CHILD_OF; /* third case: split parent dir. File is from one of existing level */ else if (data->needle_len == diff && tree) best_case = TREE_CASE_PARENT_OF; /* fourth case: both dirs have same parent */ else if (tree) best_case = TREE_CASE_HAVE_SAME_PARENT; else goto finally; data->best_len = diff; data->best_case = best_case; data->best_iter = *iter; } finally: g_free(name); return FALSE; } /* Returns TRUE if parent points to a newly added row, * caller might want to expand the relevant rows in the tree view */ static gboolean get_parent_for_file(GtkTreeStore *tree, const gchar *file, GtkTreeIter *parent) { gchar *path; GtkTreeIter iter; gint name_diff = 0; gboolean has_parent; GtkTreeModel *model = GTK_TREE_MODEL(tree); TreeForeachData data = {NULL, 0, 0, {0}, TREE_CASE_NONE}; gboolean new_row; path = g_path_get_dirname(file); /* find best opened dir */ data.needle = get_doc_folder(path); data.needle_len = strlen(data.needle); name_diff = strlen(path) - data.needle_len; gtk_tree_model_foreach(model, tree_foreach_callback, (gpointer)&data); switch (data.best_case) { case TREE_CASE_EQUALS: { *parent = data.best_iter; /* dir already open */ new_row = FALSE; break; } case TREE_CASE_CHILD_OF: { /* This dir is longer than existing so just add child */ tree_add_new_dir(tree, parent, &data.best_iter, path); new_row = TRUE; break; } case TREE_CASE_PARENT_OF: { /* More complicated logic. This dir should be a parent * of existing, so reparent existing dir. */ has_parent = gtk_tree_model_iter_parent(model, &iter, &data.best_iter); tree_add_new_dir(tree, parent, has_parent ? &iter : NULL, path); tree_reparent(tree, &data.best_iter, parent); new_row = TRUE; break; } case TREE_CASE_HAVE_SAME_PARENT: { /* Even more complicated logic. Both dirs have same * parent, so create new parent and reparent them */ GtkTreeIter new_parent; gchar *newpath = g_strndup(path, data.best_len + name_diff); has_parent = gtk_tree_model_iter_parent(model, &iter, &data.best_iter); tree_add_new_dir(tree, &new_parent, has_parent ? &iter : NULL, newpath); tree_reparent(tree, &data.best_iter, &new_parent); tree_add_new_dir(tree, parent, &new_parent, path); g_free(newpath); new_row = TRUE; break; } default: { tree_add_new_dir(tree, parent, NULL, path); new_row = TRUE; break; } } g_free(data.needle); g_free(path); return new_row; } /* Returns true when parent points to a newly added row. */ static gboolean sidebar_openfiles_add_iter(GtkTreeStore *tree, const gchar *file, GtkTreeIter *iter, GtkTreeIter *parent) { gboolean new_row; /* get_parent_for_file() might add rows for parent directories */ new_row = get_parent_for_file(tree, file, parent); /* insert row for this file */ gtk_tree_store_append(tree, iter, parent); return new_row; } static void expand_iter(GtkTreeIter *iter) { GtkTreePath *path; path = gtk_tree_model_get_path(GTK_TREE_MODEL(store_openfiles), iter); gtk_tree_view_expand_to_path(GTK_TREE_VIEW(tv.tree_openfiles), path); gtk_tree_path_free(path); } /* Also sets doc->priv->iter. * This is called recursively in sidebar_openfiles_update_all(). */ GEANY_EXPORT_SYMBOL void sidebar_openfiles_add(GeanyDocument *doc) { GtkTreeIter *iter = &doc->priv->iter; GtkTreeIter parent; const gchar *filename = DOC_FILENAME(doc); gchar *basename; const GdkColor *color = document_get_status_color(doc); static GIcon *file_icon = NULL; gboolean expand = FALSE; if (interface_prefs.openfiles_path_mode != OPENFILES_PATHS_NONE) expand = sidebar_openfiles_add_iter(store_openfiles, filename, iter, &parent); else gtk_tree_store_append(store_openfiles, iter, NULL); if (!file_icon) file_icon = ui_get_mime_icon("text/plain"); basename = g_path_get_basename(filename); gtk_tree_store_set(store_openfiles, iter, DOCUMENTS_ICON, (doc->file_type && doc->file_type->icon) ? doc->file_type->icon : file_icon, DOCUMENTS_SHORTNAME, basename, DOCUMENTS_DOCUMENT, doc, DOCUMENTS_COLOR, color, DOCUMENTS_FILENAME, DOC_FILENAME(doc), DOCUMENTS_FOLD, FALSE, -1); g_free(basename); /* Expand new parent if necessary. Beware: this is executed by unit tests * which don't create the tree view. */ if (expand && G_LIKELY(tv.tree_openfiles)) expand_iter(&parent); } /* Returns true if new_node points to a reparented directory, as a result of merging empty * directories. */ static void sidebar_openfiles_remove_iter(GtkTreeStore *tree, GtkTreeIter *iter_) { GtkTreeIter iter = *iter_; GtkTreeIter parent; GtkTreeModel *model = GTK_TREE_MODEL(store_openfiles); /* walk on top and close all orphaned parents */ while (gtk_tree_model_iter_parent(model, &parent, &iter) && gtk_tree_model_iter_n_children(model, &parent) == 1) { iter = parent; } gtk_tree_store_remove(store_openfiles, &iter); /* If, after removing, there is a single silbling left and it represents * a directory, it can be merged with the parent directory row, * essentially to reverse the effect of TREE_CASE_PARENT_OF and TREE_CASE_HAVE_SAME_PARENT * in get_doc_parent(). Inherit fold state from the merged child as well. */ if (gtk_tree_store_iter_is_valid(store_openfiles, &parent) && gtk_tree_model_iter_n_children(model, &parent) == 1) { GeanyDocument *other_doc; GtkTreeIter child, pparent; gboolean fold, has_parent; gtk_tree_model_iter_nth_child(model, &child, &parent, 0); gtk_tree_model_get(model, &child, DOCUMENTS_DOCUMENT, &other_doc, -1); if (!other_doc) { has_parent = gtk_tree_model_iter_parent(model, &pparent, &parent); tree_reparent(store_openfiles, &child, has_parent ? &pparent : NULL); gtk_tree_store_remove(store_openfiles, &parent); /* Expand if the child node was expanded before the merge. */ gtk_tree_model_get(model, &child, DOCUMENTS_FOLD, &fold, -1); if (!fold) expand_iter(&child); } } } static void openfiles_remove(GeanyDocument *doc) { if (interface_prefs.openfiles_path_mode != OPENFILES_PATHS_NONE) sidebar_openfiles_remove_iter(store_openfiles, &doc->priv->iter); else gtk_tree_store_remove(store_openfiles, &doc->priv->iter); } void sidebar_openfiles_update(GeanyDocument *doc) { GtkTreeIter *iter = &doc->priv->iter; gchar *fname; gtk_tree_model_get(GTK_TREE_MODEL(store_openfiles), iter, DOCUMENTS_FILENAME, &fname, -1); if (utils_str_equal(fname, DOC_FILENAME(doc))) { /* just update color and the icon */ const GdkColor *color = document_get_status_color(doc); GIcon *icon = doc->file_type->icon; gtk_tree_store_set(store_openfiles, iter, DOCUMENTS_COLOR, color, -1); if (icon) gtk_tree_store_set(store_openfiles, iter, DOCUMENTS_ICON, icon, -1); } else { /* path has changed, so remove and re-add */ GtkTreeSelection *treesel; gboolean sel; treesel = gtk_tree_view_get_selection(GTK_TREE_VIEW(tv.tree_openfiles)); sel = gtk_tree_selection_iter_is_selected(treesel, &doc->priv->iter); openfiles_remove(doc); sidebar_openfiles_add(doc); if (sel) gtk_tree_selection_select_iter(treesel, &doc->priv->iter); } g_free(fname); } void sidebar_openfiles_update_all(void) { guint i; gtk_tree_store_clear(store_openfiles); foreach_document (i) { sidebar_openfiles_add(documents[i]); } } void sidebar_remove_document(GeanyDocument *doc) { openfiles_remove(doc); if (GTK_IS_WIDGET(doc->priv->tag_tree)) { gtk_widget_destroy(doc->priv->tag_tree); /* make GTK release its references, if any */ /* Because it was ref'd in sidebar_update_tag_list, it needs unref'ing */ g_object_unref(doc->priv->tag_tree); doc->priv->tag_tree = NULL; } } static void on_hide_sidebar(void) { ui_prefs.sidebar_visible = FALSE; ui_sidebar_show_hide(); } static gboolean on_sidebar_display_symbol_list_show(GtkWidget *item) { gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), interface_prefs.sidebar_symbol_visible); return FALSE; } static gboolean on_sidebar_display_open_files_show(GtkWidget *item) { gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), interface_prefs.sidebar_openfiles_visible); return FALSE; } void sidebar_add_common_menu_items(GtkMenu *menu) { GtkWidget *item; item = gtk_separator_menu_item_new(); gtk_widget_show(item); gtk_container_add(GTK_CONTAINER(menu), item); item = gtk_check_menu_item_new_with_mnemonic(_("Show S_ymbol List")); gtk_container_add(GTK_CONTAINER(menu), item); g_signal_connect(item, "draw", G_CALLBACK(on_sidebar_display_symbol_list_show), NULL); gtk_widget_show(item); g_signal_connect(item, "activate", G_CALLBACK(on_list_symbol_activate), NULL); item = gtk_check_menu_item_new_with_mnemonic(_("Show _Document List")); gtk_container_add(GTK_CONTAINER(menu), item); g_signal_connect(item, "draw", G_CALLBACK(on_sidebar_display_open_files_show), NULL); gtk_widget_show(item); g_signal_connect(item, "activate", G_CALLBACK(on_list_document_activate), NULL); item = gtk_image_menu_item_new_with_mnemonic(_("H_ide Sidebar")); gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), gtk_image_new_from_stock(GTK_STOCK_CLOSE, GTK_ICON_SIZE_MENU)); gtk_widget_show(item); gtk_container_add(GTK_CONTAINER(menu), item); g_signal_connect(item, "activate", G_CALLBACK(on_hide_sidebar), NULL); } static void on_openfiles_show_paths_activate(GtkCheckMenuItem *item, gpointer user_data) { gint new_mode = GPOINTER_TO_INT(user_data); /* This is also called for menu items that became inactive (in response to activating * another one in the same group). */ if (!gtk_check_menu_item_get_active(item)) return; /* Only if the mode changes...otherwise sidebar_openfiles_update_all() recreates the * list which messes up the current selection and more. * * This can happen (for example) right after startup, when no menu item was active yet. */ if (interface_prefs.openfiles_path_mode == new_mode) return; interface_prefs.openfiles_path_mode = new_mode; sidebar_openfiles_update_all(); gtk_tree_view_expand_all(GTK_TREE_VIEW(tv.tree_openfiles)); sidebar_select_openfiles_item(document_get_current()); } static void on_list_document_activate(GtkCheckMenuItem *item, gpointer user_data) { interface_prefs.sidebar_openfiles_visible = gtk_check_menu_item_get_active(item); ui_sidebar_show_hide(); sidebar_tabs_show_hide(GTK_NOTEBOOK(main_widgets.sidebar_notebook), NULL, 0, NULL); } static void on_list_symbol_activate(GtkCheckMenuItem *item, gpointer user_data) { interface_prefs.sidebar_symbol_visible = gtk_check_menu_item_get_active(item); ui_sidebar_show_hide(); sidebar_tabs_show_hide(GTK_NOTEBOOK(main_widgets.sidebar_notebook), NULL, 0, NULL); } static void on_find_in_files(GtkMenuItem *menuitem, gpointer user_data) { GtkTreeSelection *treesel; GtkTreeIter iter; GtkTreeModel *model; GeanyDocument *doc; gchar *dir; treesel = gtk_tree_view_get_selection(GTK_TREE_VIEW(tv.tree_openfiles)); if (!gtk_tree_selection_get_selected(treesel, &model, &iter)) return; gtk_tree_model_get(model, &iter, DOCUMENTS_DOCUMENT, &doc, -1); if (!doc) { gtk_tree_model_get(model, &iter, DOCUMENTS_FILENAME, &dir, -1); } else dir = g_path_get_dirname(DOC_FILENAME(doc)); search_show_find_in_files_dialog(dir); g_free(dir); } static void on_openfiles_expand_collapse(GtkMenuItem *menuitem, gpointer user_data) { gboolean expand = GPOINTER_TO_INT(user_data); if (expand) gtk_tree_view_expand_all(GTK_TREE_VIEW(tv.tree_openfiles)); else gtk_tree_view_collapse_all(GTK_TREE_VIEW(tv.tree_openfiles)); } static void create_show_paths_popup_menu(void) { GSList *group = NULL; const gchar *items[OPENFILES_PATHS_COUNT] = { [OPENFILES_PATHS_NONE] = _("D_ocuments Only"), [OPENFILES_PATHS_LIST] = _("Show _Paths"), [OPENFILES_PATHS_TREE] = _("Show _Tree") }; for (guint i = 0; i < G_N_ELEMENTS(items); i++) { GtkWidget *w = gtk_radio_menu_item_new_with_mnemonic(group, items[i]); group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(w)); gtk_widget_show(w); gtk_container_add(GTK_CONTAINER(openfiles_popup_menu), w); g_signal_connect(w, "activate", G_CALLBACK(on_openfiles_show_paths_activate), GINT_TO_POINTER(i)); doc_items.show_paths[i] = w; } } static void create_openfiles_popup_menu(void) { GtkWidget *item; openfiles_popup_menu = gtk_menu_new(); item = gtk_image_menu_item_new_from_stock(GTK_STOCK_CLOSE, NULL); gtk_widget_show(item); gtk_container_add(GTK_CONTAINER(openfiles_popup_menu), item); g_signal_connect(item, "activate", G_CALLBACK(on_openfiles_document_action), GINT_TO_POINTER(OPENFILES_ACTION_REMOVE)); doc_items.close = item; item = gtk_separator_menu_item_new(); gtk_widget_show(item); gtk_container_add(GTK_CONTAINER(openfiles_popup_menu), item); item = gtk_image_menu_item_new_from_stock(GTK_STOCK_SAVE, NULL); gtk_widget_show(item); gtk_container_add(GTK_CONTAINER(openfiles_popup_menu), item); g_signal_connect(item, "activate", G_CALLBACK(on_openfiles_document_action), GINT_TO_POINTER(OPENFILES_ACTION_SAVE)); doc_items.save = item; item = gtk_image_menu_item_new_with_mnemonic(_("_Reload")); gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), gtk_image_new_from_stock(GTK_STOCK_REVERT_TO_SAVED, GTK_ICON_SIZE_MENU)); gtk_widget_show(item); gtk_container_add(GTK_CONTAINER(openfiles_popup_menu), item); g_signal_connect(item, "activate", G_CALLBACK(on_openfiles_document_action), GINT_TO_POINTER(OPENFILES_ACTION_RELOAD)); doc_items.reload = item; item = gtk_separator_menu_item_new(); gtk_widget_show(item); gtk_container_add(GTK_CONTAINER(openfiles_popup_menu), item); item = ui_image_menu_item_new(GTK_STOCK_FIND, _("_Find in Files...")); gtk_widget_show(item); gtk_container_add(GTK_CONTAINER(openfiles_popup_menu), item); g_signal_connect(item, "activate", G_CALLBACK(on_find_in_files), NULL); doc_items.find_in_files = item; item = gtk_separator_menu_item_new(); gtk_widget_show(item); gtk_container_add(GTK_CONTAINER(openfiles_popup_menu), item); create_show_paths_popup_menu(); item = gtk_separator_menu_item_new(); gtk_widget_show(item); gtk_container_add(GTK_CONTAINER(openfiles_popup_menu), item); doc_items.expand_all = ui_image_menu_item_new(GTK_STOCK_ADD, _("_Expand All")); gtk_widget_show(doc_items.expand_all); gtk_container_add(GTK_CONTAINER(openfiles_popup_menu), doc_items.expand_all); g_signal_connect(doc_items.expand_all, "activate", G_CALLBACK(on_openfiles_expand_collapse), GINT_TO_POINTER(TRUE)); doc_items.collapse_all = ui_image_menu_item_new(GTK_STOCK_REMOVE, _("_Collapse All")); gtk_widget_show(doc_items.collapse_all); gtk_container_add(GTK_CONTAINER(openfiles_popup_menu), doc_items.collapse_all); g_signal_connect(doc_items.collapse_all, "activate", G_CALLBACK(on_openfiles_expand_collapse), GINT_TO_POINTER(FALSE)); sidebar_add_common_menu_items(GTK_MENU(openfiles_popup_menu)); } /* compares the given data with the doc pointer from the selected row of openfiles * treeview, in case of a match the row is selected and TRUE is returned * (called indirectly from gtk_tree_model_foreach()) */ static gboolean tree_model_find_node(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data) { GeanyDocument *doc; gtk_tree_model_get(model, iter, DOCUMENTS_DOCUMENT, &doc, -1); if (doc == data) { gtk_tree_view_expand_to_path(GTK_TREE_VIEW(tv.tree_openfiles), path); gtk_tree_view_set_cursor(GTK_TREE_VIEW(tv.tree_openfiles), path, NULL, FALSE); return TRUE; } return FALSE; } void sidebar_select_openfiles_item(GeanyDocument *doc) { gtk_tree_model_foreach(GTK_TREE_MODEL(store_openfiles), tree_model_find_node, doc); } /* callbacks */ static void document_action(GeanyDocument *doc, gint action) { if (! DOC_VALID(doc)) return; switch (action) { case OPENFILES_ACTION_REMOVE: { document_close(doc); break; } case OPENFILES_ACTION_SAVE: { document_save_file(doc, FALSE); break; } case OPENFILES_ACTION_RELOAD: { document_reload_prompt(doc, NULL); break; } } } /* Collects all documents under a given iter, filling @doc_array */ static void on_openfiles_document_action_collect(GtkTreeModel *model, GtkTreeIter *iter, GPtrArray *doc_array) { GeanyDocument *doc; gtk_tree_model_get(model, iter, DOCUMENTS_DOCUMENT, &doc, -1); if (doc) { g_ptr_array_add(doc_array, doc); } else { /* parent item selected */ GtkTreeIter child; if (gtk_tree_model_iter_children(model, &child, iter)) { do { on_openfiles_document_action_collect(model, &child, doc_array); } while (gtk_tree_model_iter_next(model, &child)); } } } static void on_openfiles_document_action(GtkMenuItem *menuitem, gpointer user_data) { GtkTreeIter iter; GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tv.tree_openfiles)); GtkTreeModel *model; gint action = GPOINTER_TO_INT(user_data); if (gtk_tree_selection_get_selected(selection, &model, &iter)) { GPtrArray *doc_array = g_ptr_array_new(); on_openfiles_document_action_collect(model, &iter, doc_array); for (guint i = 0; i < doc_array->len; i++) document_action(g_ptr_array_index(doc_array, i), action); g_ptr_array_free(doc_array, TRUE); } } static void change_focus_to_editor(GeanyDocument *doc, GtkWidget *source_widget) { if (may_steal_focus) document_try_focus(doc, source_widget); may_steal_focus = FALSE; } static gboolean openfiles_go_to_selection(GtkTreeSelection *selection, guint keyval) { GtkTreeIter iter; GtkTreeModel *model; GeanyDocument *doc = NULL; /* use switch_notebook_page to ignore changing the notebook page because it is already done */ if (gtk_tree_selection_get_selected(selection, &model, &iter) && ! ignore_callback) { gtk_tree_model_get(model, &iter, DOCUMENTS_DOCUMENT, &doc, -1); if (! doc) return FALSE; /* parent */ /* switch to the doc and grab the focus */ document_show_tab(doc); if (keyval != GDK_KEY_space) change_focus_to_editor(doc, tv.tree_openfiles); } return FALSE; } static gboolean taglist_go_to_selection(GtkTreeSelection *selection, guint keyval, guint state) { GtkTreeIter iter; GtkTreeModel *model; gint line = 0; gboolean handled = TRUE; if (gtk_tree_selection_get_selected(selection, &model, &iter)) { TMTag *tag; gtk_tree_model_get(model, &iter, SYMBOLS_COLUMN_TAG, &tag, -1); if (! tag) return FALSE; line = tag->line; if (line > 0) { GeanyDocument *doc = document_get_current(); if (doc != NULL) { navqueue_goto_line(doc, doc, line); state = keybindings_get_modifiers(state); if (keyval != GDK_KEY_space && ! (state & GEANY_PRIMARY_MOD_MASK)) change_focus_to_editor(doc, NULL); else handled = FALSE; } } tm_tag_unref(tag); } return handled; } static gboolean sidebar_key_press_cb(GtkWidget *widget, GdkEventKey *event, gpointer user_data) { may_steal_focus = FALSE; if (ui_is_keyval_enter_or_return(event->keyval) || event->keyval == GDK_KEY_space) { GtkWidgetClass *widget_class = GTK_WIDGET_GET_CLASS(widget); GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(widget)); may_steal_focus = TRUE; /* force the TreeView handler to run before us for it to do its job (selection & stuff). * doing so will prevent further handlers to be run in most cases, but the only one is our * own, so guess it's fine. */ if (widget_class->key_press_event) widget_class->key_press_event(widget, event); if (widget == tv.tree_openfiles) /* tag and doc list have separate handlers */ openfiles_go_to_selection(selection, event->keyval); else taglist_go_to_selection(selection, event->keyval, event->state); return TRUE; } return FALSE; } static gboolean sidebar_button_press_cb(GtkWidget *widget, GdkEventButton *event, G_GNUC_UNUSED gpointer user_data) { GtkTreeSelection *selection; GtkWidgetClass *widget_class = GTK_WIDGET_GET_CLASS(widget); gboolean handled = FALSE; /* force the TreeView handler to run before us for it to do its job (selection & stuff). * doing so will prevent further handlers to be run in most cases, but the only one is our own, * so guess it's fine. */ if (widget_class->button_press_event) handled = widget_class->button_press_event(widget, event); selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(widget)); may_steal_focus = TRUE; if (event->type == GDK_2BUTTON_PRESS) { /* double click on parent node(section) expands/collapses it */ GtkTreeModel *model; GtkTreeIter iter; if (gtk_tree_selection_get_selected(selection, &model, &iter)) { if (gtk_tree_model_iter_has_child(model, &iter)) { GtkTreePath *path = gtk_tree_model_get_path(model, &iter); if (gtk_tree_view_row_expanded(GTK_TREE_VIEW(widget), path)) gtk_tree_view_collapse_row(GTK_TREE_VIEW(widget), path); else gtk_tree_view_expand_row(GTK_TREE_VIEW(widget), path, FALSE); gtk_tree_path_free(path); return TRUE; } } } else if (event->button == 1) { /* allow reclicking of taglist treeview item */ if (widget == tv.tree_openfiles) { openfiles_go_to_selection(selection, 0); handled = TRUE; } else handled = taglist_go_to_selection(selection, 0, event->state); } else if (event->button == 2) { if (widget == tv.tree_openfiles) on_openfiles_document_action(NULL, GINT_TO_POINTER(OPENFILES_ACTION_REMOVE)); } else if (event->button == 3) { if (widget == tv.tree_openfiles) { if (!openfiles_popup_menu) create_openfiles_popup_menu(); /* update menu item sensitivity */ documents_menu_update(selection); gtk_menu_popup_at_pointer(GTK_MENU(openfiles_popup_menu), (GdkEvent *) event); } else { gtk_menu_popup_at_pointer(GTK_MENU(tv.popup_taglist), (GdkEvent *) event); } handled = TRUE; } return handled; } static void documents_menu_update(GtkTreeSelection *selection) { GtkTreeModel *model; GtkTreeIter iter; gboolean sel, path; gchar *shortname = NULL; GeanyDocument *doc = NULL; /* maybe no selection e.g. if ctrl-click deselected */ sel = gtk_tree_selection_get_selected(selection, &model, &iter); if (sel) { gtk_tree_model_get(model, &iter, DOCUMENTS_DOCUMENT, &doc, DOCUMENTS_SHORTNAME, &shortname, -1); } path = !EMPTY(shortname) && (g_path_is_absolute(shortname) || (app->project && g_str_has_prefix(shortname, app->project->name))); /* can close all, save all (except shortname), but only reload individually ATM */ gtk_widget_set_sensitive(doc_items.close, sel); gtk_widget_set_sensitive(doc_items.save, (doc && doc->real_path) || path); gtk_widget_set_sensitive(doc_items.reload, doc && doc->real_path); gtk_widget_set_sensitive(doc_items.find_in_files, sel); g_free(shortname); gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(doc_items.show_paths[interface_prefs.openfiles_path_mode]), TRUE); gtk_widget_set_sensitive(doc_items.expand_all, interface_prefs.openfiles_path_mode); gtk_widget_set_sensitive(doc_items.collapse_all, interface_prefs.openfiles_path_mode); } static StashGroup *stash_group = NULL; static void on_load_settings(void) { if (interface_prefs.openfiles_path_mode < 0 || interface_prefs.openfiles_path_mode >= OPENFILES_PATHS_COUNT) interface_prefs.openfiles_path_mode = OPENFILES_PATHS_TREE; tag_window = ui_lookup_widget(main_widgets.window, "scrolledwindow2"); prepare_openfiles(); /* note: ui_prefs.sidebar_page is reapplied after plugins are loaded */ stash_group_display(stash_group, NULL); sidebar_tabs_show_hide(GTK_NOTEBOOK(main_widgets.sidebar_notebook), NULL, 0, NULL); } static void on_save_settings(void) { stash_group_update(stash_group, NULL); sidebar_tabs_show_hide(GTK_NOTEBOOK(main_widgets.sidebar_notebook), NULL, 0, NULL); } static void on_sidebar_switch_page(GtkNotebook *notebook, gpointer page, guint page_num, gpointer user_data) { if (page_num == TREEVIEW_SYMBOL) sidebar_update_tag_list(document_get_current(), FALSE); } void sidebar_init(void) { StashGroup *group; group = stash_group_new(PACKAGE); stash_group_add_widget_property(group, &ui_prefs.sidebar_page, "sidebar_page", GINT_TO_POINTER(0), main_widgets.sidebar_notebook, "page", 0); configuration_add_session_group(group, FALSE); stash_group = group; /* Delay building documents treeview until sidebar font has been read and prefs are sanitized */ g_signal_connect(geany_object, "load-settings", on_load_settings, NULL); g_signal_connect(geany_object, "save-settings", on_save_settings, NULL); g_signal_connect(main_widgets.sidebar_notebook, "page-added", G_CALLBACK(sidebar_tabs_show_hide), NULL); g_signal_connect(main_widgets.sidebar_notebook, "page-removed", G_CALLBACK(sidebar_tabs_show_hide), NULL); /* tabs may have changed when sidebar is reshown */ g_signal_connect(main_widgets.sidebar_notebook, "show", G_CALLBACK(sidebar_tabs_show_hide), NULL); g_signal_connect_after(main_widgets.sidebar_notebook, "switch-page", G_CALLBACK(on_sidebar_switch_page), NULL); } #define WIDGET(w) w && GTK_IS_WIDGET(w) void sidebar_finalize(void) { if (WIDGET(tv.default_tag_tree)) { gtk_widget_destroy(tv.default_tag_tree); /* make GTK release its references, if any... */ g_object_unref(tv.default_tag_tree); /* ...and release our own */ } if (WIDGET(tv.popup_taglist)) gtk_widget_destroy(tv.popup_taglist); if (WIDGET(openfiles_popup_menu)) gtk_widget_destroy(openfiles_popup_menu); } void sidebar_focus_openfiles_tab(void) { if (ui_prefs.sidebar_visible && interface_prefs.sidebar_openfiles_visible) { GtkNotebook *notebook = GTK_NOTEBOOK(main_widgets.sidebar_notebook); gtk_notebook_set_current_page(notebook, TREEVIEW_OPENFILES); gtk_widget_grab_focus(tv.tree_openfiles); } } void sidebar_focus_symbols_tab(void) { if (ui_prefs.sidebar_visible && interface_prefs.sidebar_symbol_visible) { GtkNotebook *notebook = GTK_NOTEBOOK(main_widgets.sidebar_notebook); GtkWidget *symbol_list_scrollwin = gtk_notebook_get_nth_page(notebook, TREEVIEW_SYMBOL); gtk_notebook_set_current_page(notebook, TREEVIEW_SYMBOL); gtk_widget_grab_focus(gtk_bin_get_child(GTK_BIN(symbol_list_scrollwin))); } } static void sidebar_tabs_show_hide(GtkNotebook *notebook, GtkWidget *child, guint page_num, gpointer data) { gint tabs = gtk_notebook_get_n_pages(notebook); if (interface_prefs.sidebar_symbol_visible == FALSE) tabs--; if (interface_prefs.sidebar_openfiles_visible == FALSE) tabs--; gtk_notebook_set_show_tabs(notebook, (tabs > 1)); } geany-2.0/src/filetypesprivate.h0000644000175000017500000000374014514252267013752 00000000000000/* * filetypesprivate.h - this file is part of Geany, a fast and lightweight IDE * * Copyright 2008 The Geany contributors * * This program 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; either version 2 of the License, or * (at your option) any later version. * * This program 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef GEANY_FILETYPES_PRIVATE_H #define GEANY_FILETYPES_PRIVATE_H 1 #include "build.h" #include G_BEGIN_DECLS /* Private GeanyFiletype fields */ typedef struct GeanyFiletypePrivate { GtkWidget *menu_item; /* holds a pointer to the menu item for this filetype */ gboolean keyfile_loaded; GRegex *error_regex; gchar *last_error_pattern; gboolean custom; gint symbol_list_sort_mode; gboolean xml_indent_tags; /* XML tag autoindentation, for HTML and XML filetypes */ GSList *tag_files; gboolean warn_color_scheme; gboolean user_extensions; // true if extensions were read from user config file /* TODO: move to structure in build.h and only put a pointer here */ GeanyBuildCommand *filecmds; GeanyBuildCommand *ftdefcmds; GeanyBuildCommand *execcmds; GeanyBuildCommand *homefilecmds; GeanyBuildCommand *homeexeccmds; GeanyBuildCommand *projfilecmds; GeanyBuildCommand *projexeccmds; gint project_list_entry; gchar *projerror_regex_string; gchar *homeerror_regex_string; } GeanyFiletypePrivate; G_END_DECLS #endif /* GEANY_FILETYPES_PRIVATE_H */ geany-2.0/src/about.c0000644000175000017500000005003314514252267011455 00000000000000/* * about.c - this file is part of Geany, a fast and lightweight IDE * * Copyright 2005 The Geany contributors * * This program 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; either version 2 of the License, or * (at your option) any later version. * * This program 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /* * About dialog and credits. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include "about.h" #include "app.h" #include "gb.c" #include "geany.h" #include "geanywraplabel.h" #include "main.h" #include "support.h" #include "ui_utils.h" #include "utils.h" #include #define HEADER "Geany %s" #define INFO "%s" #define CODENAME "\"" GEANY_CODENAME "\"" #define BUILDDATE "%s" #define RUNTIME BUILDDATE #define COPYRIGHT _("Copyright (c) 2005\nThe Geany contributors") static const gchar *translators[][2] = { { "ar", "Fayssal Chamekh <chamfay@gmail.com>"}, { "ast", "Marcos Costales <marcoscostales@gmail.com>"}, { "be_BY", "Yura Siamashka <yurand2@gmail.com>" }, { "bg", "Dilyan Rusev <dilyanrusev@gmail.com>" }, { "ca_ES", "Robert Buj <rbuj@fedoraproject.org>\nToni Garcia-Navarro <topi@elpiset.net>" }, { "cs_CZ", "Petr Messner <messa@messa.cz>\nAnna Talianova <anickat1@gmail.com>" }, { "de_DE", "Frank Lanitz <frank@frank.uvena.de>\nDominic Hopf <dmaphy@googlemail.com>" }, { "el", "Stavros Temertzidis <bullgr@gmail.com>" }, { "en_GB", "Jeff Bailes <thepizzaking@gmail.com>" }, { "es", "Antonio Jiménez González <tonificante@hotmail.com>\nLucas Vieites <lucasvieites@gmail.com>" }, { "eu", "Asier Iturralde Sarasola <asier.iturralde@gmail.com>"}, { "fa", "Moein Owhadi Kareshk <moein.owhadi@gmail.com>"}, { "fi", "Harri Koskinen <harri@fastmonkey.org>\nJari Rahkonen <jari.rahkonen@pp1.inet.fi>" }, { "fr", "Jean-Philippe Moal <skateinmars@skateinmars.net>" }, { "gl", "José Manuel Castroagudín Silva <chavescesures@gmail.com>"}, { "hi", "Asheesh Ranjan <asheeshranjan1@gmail.com>"}, { "he", "Yosef Or Boczko <yoseforb@gmail.com>"}, { "hu", "Gabor Kmetyko <kg_kilo@freemail.hu>" }, { "id", "Fajar Wahyu <fajarwahyuabdillah@gmail.com>\n" "Samsul Ma'arif <mail@samsul.web.id>\n" "Bervianto Leo Pratama <bervianto.leo@gmail.com>" }, { "it", "Max Baldinelli <m.baldinelli@agora.it>,\nDario Santomarco <dariello@yahoo.it>" }, { "ja", "Tarot Osuji <tarot@sdf.lonestar.org>\nChikahiro Masami <cmasa.z321@gmail.com>" }, { "ko", "Park Jang-heon <dotkabi@gmail.com>" }, { "kk", "Baurzhan Muftakhidinov <baurthefirst@gmail.com>"}, { "lt", "Algimantas MargeviÄius <margevicius.algimantas@gmail.com>"}, { "lb", "Laurent Hoeltgen <hoeltgman@gmail.com>" }, { "mn", "tsetsee <tsetsee.yugi@gmail.com>"}, { "nl", "Benno Schulenberg <benno@vertaalt.nl>\nPeter Scholtens <peter.scholtens@freedom.nl>\nAyke van Laethem <aykevanlaethem@gmail.com>" }, { "pl", "Wojciech Åšwiderski <woj.swiderski@gmail.com>"}, { "pt_BR", "Alexandra Moreire <alexandream@gmail.com>\n" "Adrovane Marques Kade <adrovane@gmail.com>\n" "Rafael Peregrino da Silva <rperegrino@linuxnewmedia.com.br>"}, { "ro", "Alex Eftimie <alex@rosedu.org>" }, { "ru", "brahmann_ <brahmann@lifec0re.net>,\nNikita E. Shalaev <nshalaev@eu.spb.ru>" }, { "sk", "Andrej Herceg <chrono.i18n@gmail.com>" }, { "sl", "Jože Klepec <joze.klepec@siol.net>"}, { "sv", "Tony Mattsson <superxorn@gmail.com>" }, { "sr", "Nikola Radovanovic <cobisimo@gmail.com>"}, { "tr", "Gürkan Gür <seqizz@gmail.com>"}, { "uk", "Artur Shepilko <nomadbyte@gmail.com>" }, { "vi_VN", "Clytie Siddall <clytie@riverland.net.au>" }, { "zh_CN", "Dormouse Young <mouselinux@163.com>,\nXhacker Liu <liu.dongyuan@gmail.com>" }, { "zh_TW", "KoViCH <kovich.ian@gmail.com>\nWei-Lun Chao <chaoweilun@gmail.com>" } }; static const guint translators_len = G_N_ELEMENTS(translators); static const gchar *prev_translators[][2] = { { "es", "Damián Viano <debian@damianv.com.ar>\nNacho Cabanes <ncabanes@gmail.com>" }, { "pl", "Jacek Wolszczak <shutdownrunner@o2.pl>\nJarosÅ‚aw Foksa <jfoksa@gmail.com>" }, { "nl", "Kurt De Bree <kdebree@telenet.be>" }, { "sk", "Tomáš Vadina <kyberdev@gmail.com>" }, { "uk", "Boris Dibrov <dibrov.bor@gmail.com>" } }; static const guint prev_translators_len = G_N_ELEMENTS(prev_translators); static const gchar *contributors = "Adam Ples, " "Alexander Rodin, Alexey Antipov, Andrew Rowland, Anh Phạm, blackdog, Bo Lorentsen, Bob Doan, " "BronisÅ‚aw BiaÅ‚ek, Can Koy, Catalin Marinas, " "Chris Macksey, Christoph Berg, Colomban Wendling, Conrad Steenberg, Daniel Richard G., " "Daniel Marjamaki, Dave Moore, " "Dimitar Zhekov, Dirk Weber, Elias Pschernig, Eric Forgeot, " "Erik de Castro Lopo, Eugene Arshinov, Felipe Pena, François Cami, " "Giuseppe Torelli, Guillaume de Rorthais, Guillaume Hoffmann, Herbert Voss, Jason Oster, " "Jean-François Wauthy, Jeff Pohlmeyer, Jesse Mayes, Jiří Techet, " "John Gabriele, Jon Senior, Jon Strait, Josef Whiter, " "Jörn Reder, Kelvin Gardiner, Kevin Ellwood, Kristoffer A. TjernÃ¥s, Lex Trotman, " "Manuel Bua, Mário Silva, Marko Peric, Matthew Brush, Matti MÃ¥rds, " "Moritz Barsnick, Nicolas Sierro, Ondrej Donek, Peter Strand, Philipp Gildein, " "Pierre Joye, Rob van der Linde, " "Robert McGinley, Roland Baudin, Ross McKay, S Jagannathan, Saleem Abdulrasool, " "Sebastian Kraft, Shiv, Slava Semushin, Stefan Oltmanns, Tamim, Taylor Venable, " "Thomas Huth, Thomas Martitz, Tomás Vírseda, " "Tyler Mulligan, Walery Studennikov, Yura Siamashka"; static void header_eventbox_style_set(GtkWidget *widget); static void header_label_style_set(GtkWidget *widget); static void homepage_clicked(GtkButton *button, gpointer data); #define ROW(text, row, col, x_align, y_padding, col_span) \ label = gtk_label_new((text)); \ gtk_table_attach(GTK_TABLE(table), label, (col), (col) + (col_span) + 1, (row), (row) + 1, \ (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (GTK_FILL), 0, (y_padding)); \ gtk_label_set_use_markup(GTK_LABEL(label), TRUE); \ gtk_misc_set_alignment(GTK_MISC(label), (x_align), 0); static GtkWidget *create_dialog(void) { GtkWidget *dialog; GtkWidget *header_image; GtkWidget *header_label; GtkWidget *label_info; GtkWidget *codename_label; GtkWidget *builddate_label; GtkWidget *runtime_label; GtkWidget *url_button; GtkWidget *cop_label; GtkWidget *label; GtkWidget *license_textview; GtkWidget *notebook; GtkWidget *box; GtkWidget *credits_scrollwin; GtkWidget *table; GtkWidget *license_scrollwin; GtkWidget *info_box; GtkWidget *header_hbox; GtkWidget *header_eventbox; GtkTextBuffer* tb; gchar *license_text = NULL; gchar buffer[512]; gchar buffer2[128]; guint i, row = 0; gchar *build_date; dialog = gtk_dialog_new(); /* configure dialog */ gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(main_widgets.window)); gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_CENTER_ON_PARENT); gtk_window_set_title(GTK_WINDOW(dialog), _("About Geany")); gtk_window_set_icon_name(GTK_WINDOW(dialog), "geany"); gtk_widget_set_name(dialog, "GeanyDialog"); gtk_dialog_add_button(GTK_DIALOG(dialog), GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE); gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_CLOSE); g_signal_connect(dialog, "key-press-event", G_CALLBACK(gb_on_key_pressed), NULL); /* create header */ header_eventbox = gtk_event_box_new(); gtk_widget_show(header_eventbox); header_hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 12); gtk_container_set_border_width(GTK_CONTAINER(header_hbox), 4); gtk_widget_show(header_hbox); gtk_container_add(GTK_CONTAINER(header_eventbox), header_hbox); header_image = gtk_image_new_from_icon_name("geany", GTK_ICON_SIZE_DIALOG); gtk_box_pack_start(GTK_BOX(header_hbox), header_image, FALSE, FALSE, 0); header_label = gtk_label_new(NULL); gtk_label_set_use_markup(GTK_LABEL(header_label), TRUE); /* print the subversion revision generated by ./configure if it is available */ g_snprintf(buffer, sizeof(buffer), HEADER, main_get_version_string()); gtk_label_set_markup(GTK_LABEL(header_label), buffer); gtk_widget_show(header_label); gtk_box_pack_start(GTK_BOX(header_hbox), header_label, FALSE, FALSE, 0); header_eventbox_style_set(header_eventbox); header_label_style_set(header_label); g_signal_connect_after(header_eventbox, "style-set", G_CALLBACK(header_eventbox_style_set), NULL); g_signal_connect_after(header_label, "style-set", G_CALLBACK(header_label_style_set), NULL); gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), header_eventbox, FALSE, FALSE, 0); /* create notebook */ notebook = gtk_notebook_new(); gtk_widget_show(notebook); gtk_container_set_border_width(GTK_CONTAINER(notebook), 2); gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), notebook, TRUE, TRUE, 0); /* create "Info" tab */ info_box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); gtk_container_set_border_width(GTK_CONTAINER(info_box), 6); gtk_widget_show(info_box); label_info = gtk_label_new(NULL); gtk_label_set_justify(GTK_LABEL(label_info), GTK_JUSTIFY_CENTER); gtk_label_set_selectable(GTK_LABEL(label_info), TRUE); gtk_label_set_use_markup(GTK_LABEL(label_info), TRUE); g_snprintf(buffer, sizeof(buffer), INFO, _("A fast and lightweight IDE")); gtk_label_set_markup(GTK_LABEL(label_info), buffer); gtk_misc_set_padding(GTK_MISC(label_info), 2, 11); gtk_widget_show(label_info); gtk_box_pack_start(GTK_BOX(info_box), label_info, FALSE, FALSE, 0); /* Codename label */ codename_label = gtk_label_new(NULL); gtk_label_set_justify(GTK_LABEL(codename_label), GTK_JUSTIFY_CENTER); gtk_label_set_selectable(GTK_LABEL(codename_label), TRUE); gtk_label_set_use_markup(GTK_LABEL(codename_label), TRUE); gtk_label_set_markup(GTK_LABEL(codename_label), CODENAME); gtk_misc_set_padding(GTK_MISC(codename_label), 2, 8); gtk_widget_show(codename_label); gtk_box_pack_start(GTK_BOX(info_box), codename_label, FALSE, FALSE, 0); /* build date label */ builddate_label = gtk_label_new(NULL); gtk_label_set_justify(GTK_LABEL(builddate_label), GTK_JUSTIFY_CENTER); gtk_label_set_selectable(GTK_LABEL(builddate_label), TRUE); gtk_label_set_use_markup(GTK_LABEL(builddate_label), TRUE); build_date = utils_parse_and_format_build_date(__DATE__); g_snprintf(buffer2, sizeof(buffer2), _("(built on or after %s)"), build_date); g_free(build_date); g_snprintf(buffer, sizeof(buffer), BUILDDATE, buffer2); gtk_label_set_markup(GTK_LABEL(builddate_label), buffer); gtk_misc_set_padding(GTK_MISC(builddate_label), 2, 2); gtk_widget_show(builddate_label); gtk_box_pack_start(GTK_BOX(info_box), builddate_label, FALSE, FALSE, 0); /* GTK+/GLib runtime version label */ runtime_label = gtk_label_new(NULL); gtk_label_set_justify(GTK_LABEL(runtime_label), GTK_JUSTIFY_CENTER); gtk_label_set_selectable(GTK_LABEL(runtime_label), TRUE); gtk_label_set_use_markup(GTK_LABEL(runtime_label), TRUE); g_snprintf(buffer2, sizeof(buffer2), _("Using GTK+ v%u.%u.%u and GLib v%u.%u.%u runtime libraries"), gtk_major_version, gtk_minor_version, gtk_micro_version, glib_major_version, glib_minor_version, glib_micro_version); g_snprintf(buffer, sizeof(buffer), RUNTIME, buffer2); gtk_label_set_markup(GTK_LABEL(runtime_label), buffer); gtk_misc_set_padding(GTK_MISC(runtime_label), 2, 2); gtk_widget_show(runtime_label); gtk_box_pack_start(GTK_BOX(info_box), runtime_label, FALSE, FALSE, 0); box = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL); url_button = gtk_button_new(); gtk_button_set_relief(GTK_BUTTON(url_button), GTK_RELIEF_NONE); g_signal_connect(url_button, "clicked", G_CALLBACK(homepage_clicked), (gpointer)GEANY_HOMEPAGE); label = gtk_label_new(NULL); gtk_label_set_text(GTK_LABEL(label), GEANY_HOMEPAGE); gtk_widget_show(label); gtk_container_add(GTK_CONTAINER(url_button), label); gtk_widget_show(url_button); gtk_box_pack_start(GTK_BOX(box), url_button, FALSE, FALSE, 0); gtk_widget_show(box); gtk_box_pack_start(GTK_BOX(info_box), box, FALSE, FALSE, 10); /* copyright label */ cop_label = gtk_label_new(NULL); gtk_label_set_justify(GTK_LABEL(cop_label), GTK_JUSTIFY_CENTER); gtk_label_set_selectable(GTK_LABEL(cop_label), FALSE); gtk_label_set_use_markup(GTK_LABEL(cop_label), TRUE); gtk_label_set_markup(GTK_LABEL(cop_label), COPYRIGHT); gtk_misc_set_padding(GTK_MISC(cop_label), 2, 10); gtk_widget_show(cop_label); gtk_box_pack_start(GTK_BOX(info_box), cop_label, FALSE, FALSE, 0); /*gtk_container_add(GTK_CONTAINER(info_box), cop_label); */ label = gtk_label_new(_("Info")); gtk_widget_show(label); gtk_widget_show_all(info_box); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), info_box, label); /* create "Credits" tab */ credits_scrollwin = gtk_scrolled_window_new(NULL, NULL); gtk_container_set_border_width(GTK_CONTAINER(credits_scrollwin), 6); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(credits_scrollwin), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); table = gtk_table_new(23 + translators_len + prev_translators_len, 3, FALSE); gtk_table_set_col_spacings(GTK_TABLE(table), 10); row = 0; g_snprintf(buffer, sizeof(buffer), "%s", _("Developers")); label = gtk_label_new(buffer); gtk_table_attach(GTK_TABLE(table), label, 0, 2, row, row + 1, GTK_FILL, 0, 0, 5); gtk_label_set_use_markup(GTK_LABEL(label), TRUE); gtk_misc_set_alignment(GTK_MISC(label), 0, 0); row++; g_snprintf(buffer, sizeof(buffer), "Colomban Wendling - %s", _("maintainer")); ROW(buffer, row, 0, 0, 0, 1); row++; ROW("<lists.ban@herbesfolles.org>", row, 0, 0, 0, 1); row++; ROW("", row, 0, 0, 0, 0); row++; g_snprintf(buffer, sizeof(buffer), "Nick Treleaven - %s", _("developer")); ROW(buffer, row, 0, 0, 0, 1); row++; ROW("<nick.treleaven@btinternet.com>", row, 0, 0, 0, 1); row++; ROW("", row, 0, 0, 0, 0); row++; g_snprintf(buffer, sizeof(buffer), "Enrico Tröger - %s", _("developer")); ROW(buffer, row, 0, 0, 0, 1); row++; ROW("<enrico.troeger@uvena.de>", row, 0, 0, 0, 1); row++; ROW("", row, 0, 0, 0, 0); row++; g_snprintf(buffer, sizeof(buffer), "Matthew Brush - %s", _("developer")); ROW(buffer, row, 0, 0, 0, 1); row++; ROW("<mbrush@codebrainz.ca>", row, 0, 0, 0, 1); row++; ROW("", row, 0, 0, 0, 0); row++; g_snprintf(buffer, sizeof(buffer), "Frank Lanitz - %s", _("translation maintainer")); ROW(buffer, row, 0, 0, 0, 1); row++; ROW("<frank@frank.uvena.de>", row, 0, 0, 0, 1); row++; ROW("", row, 0, 0, 0, 0); row++; g_snprintf(buffer, sizeof(buffer), "%s", _("Translators")); label = gtk_label_new(buffer); gtk_table_attach(GTK_TABLE(table), label, 0, 2, row, row + 1, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 5); gtk_label_set_use_markup(GTK_LABEL(label), TRUE); gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); row++; for (i = 0; i < translators_len; i++) { ROW(translators[i][0], row, 0, 1, 4, 0); ROW(translators[i][1], row, 1, 0, 4, 0); row++; } ROW("", row, 0, 0, 0, 0); row++; g_snprintf(buffer, sizeof(buffer), "%s", _("Previous Translators")); label = gtk_label_new(buffer); gtk_table_attach(GTK_TABLE(table), label, 0, 2, row, row + 1, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 5); gtk_label_set_use_markup(GTK_LABEL(label), TRUE); gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); row++; for (i = 0; i < prev_translators_len; i++) { ROW(prev_translators[i][0], row, 0, 1, 4, 0); ROW(prev_translators[i][1], row, 1, 0, 4, 0); row++; } ROW("", row, 0, 0, 0, 0); row++; g_snprintf(buffer, sizeof(buffer), "%s", _("Contributors")); label = gtk_label_new(buffer); gtk_table_attach(GTK_TABLE(table), label, 0, 2, row, row + 1, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 5); gtk_label_set_use_markup(GTK_LABEL(label), TRUE); gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); row++; g_snprintf(buffer, sizeof(buffer), _("Some of the many contributors (for a more detailed list, see the file %s):"), #ifdef G_OS_WIN32 "Thanks.txt" #else "THANKS" #endif ); label = geany_wrap_label_new(buffer); gtk_table_attach(GTK_TABLE(table), label, 0, 2, row, row + 1, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 5); gtk_label_set_use_markup(GTK_LABEL(label), TRUE); gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); row++; label = geany_wrap_label_new(contributors); gtk_table_attach(GTK_TABLE(table), label, 0, 2, row, row + 1, (GtkAttachOptions) (GTK_FILL | GTK_EXPAND), (GtkAttachOptions) (0), 0, 5); gtk_label_set_use_markup(GTK_LABEL(label), TRUE); gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); row++; gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(credits_scrollwin), table); gtk_viewport_set_shadow_type(GTK_VIEWPORT(gtk_widget_get_parent(table)), GTK_SHADOW_NONE); gtk_widget_show_all(table); label = gtk_label_new(_("Credits")); gtk_widget_show(label); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), credits_scrollwin, label); /* create "License" tab */ license_scrollwin = gtk_scrolled_window_new(NULL, NULL); gtk_container_set_border_width(GTK_CONTAINER(license_scrollwin), 6); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(license_scrollwin), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(license_scrollwin), GTK_SHADOW_IN); license_textview = gtk_text_view_new(); gtk_text_view_set_left_margin(GTK_TEXT_VIEW(license_textview), 2); gtk_text_view_set_right_margin(GTK_TEXT_VIEW(license_textview), 2); gtk_text_view_set_editable(GTK_TEXT_VIEW(license_textview), FALSE); gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(license_textview), FALSE); gtk_widget_show(license_textview); gtk_container_add(GTK_CONTAINER(license_scrollwin), license_textview); label = gtk_label_new(_("License")); gtk_widget_show(label); g_snprintf(buffer, sizeof(buffer), "%s" G_DIR_SEPARATOR_S "GPL-2", app->datadir); g_file_get_contents(buffer, &license_text, NULL, NULL); if (license_text == NULL) { license_text = g_strdup( _("License text could not be found, please visit http://www.gnu.org/licenses/gpl-2.0.txt to view it online.")); } tb = gtk_text_view_get_buffer(GTK_TEXT_VIEW(license_textview)); gtk_text_buffer_set_text(tb, license_text, -1); g_free(license_text); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), license_scrollwin, label); gtk_widget_show_all(dialog); return dialog; } void about_dialog_show(void) { GtkWidget *dialog; dialog = create_dialog(); gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); } static void header_eventbox_style_set(GtkWidget *widget) { GtkStyle *style = gtk_widget_get_style(widget); if (! gdk_color_equal(&style->bg[GTK_STATE_NORMAL], &style->bg[GTK_STATE_SELECTED])) gtk_widget_modify_bg(widget, GTK_STATE_NORMAL, &style->bg[GTK_STATE_SELECTED]); } static void header_label_style_set(GtkWidget *widget) { GtkStyle *style = gtk_widget_get_style(widget); if (! gdk_color_equal(&style->fg[GTK_STATE_NORMAL], &style->fg[GTK_STATE_SELECTED])) gtk_widget_modify_fg(widget, GTK_STATE_NORMAL, &style->fg[GTK_STATE_SELECTED]); } static void homepage_clicked(GtkButton *button, gpointer data) { utils_open_browser(data); } geany-2.0/src/editor.c0000644000175000017500000044562414514252267011647 00000000000000/* * editor.c - this file is part of Geany, a fast and lightweight IDE * * Copyright 2005 The Geany contributors * * This program 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; either version 2 of the License, or * (at your option) any later version. * * This program 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /** * @file editor.h * Editor-related functions for @ref GeanyEditor. * Geany uses the Scintilla editing widget, and this file is mostly built around * Scintilla's functionality. * @see sciwrappers.h. */ /* Callbacks for the Scintilla widget (ScintillaObject). * Most important is the sci-notify callback, handled in on_editor_notification(). * This includes auto-indentation, comments, auto-completion, calltips, etc. * Also some general Scintilla-related functions. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include "editor.h" #include "app.h" #include "callbacks.h" #include "dialogs.h" #include "documentprivate.h" #include "filetypesprivate.h" #include "geanyobject.h" #include "highlighting.h" #include "keybindings.h" #include "main.h" #include "prefs.h" #include "projectprivate.h" #include "sciwrappers.h" #include "support.h" #include "symbols.h" #include "templates.h" #include "ui_utils.h" #include "utils.h" #include "SciLexer.h" #include #include #include #include static GHashTable *snippet_hash = NULL; static GtkAccelGroup *snippet_accel_group = NULL; static gboolean autocomplete_scope_shown = FALSE; static const gchar geany_cursor_marker[] = "__GEANY_CURSOR_MARKER__"; /* holds word under the mouse or keyboard cursor */ static gchar current_word[GEANY_MAX_WORD_LENGTH]; /* Initialised in keyfile.c. */ GeanyEditorPrefs editor_prefs; EditorInfo editor_info = {current_word, -1}; static struct { gchar *text; gboolean set; gchar *last_word; guint tag_index; gint pos; ScintillaObject *sci; } calltip = {NULL, FALSE, NULL, 0, 0, NULL}; static gchar indent[100]; static void on_new_line_added(GeanyEditor *editor); static gboolean handle_xml(GeanyEditor *editor, gint pos, gchar ch); static void insert_indent_after_line(GeanyEditor *editor, gint line); static void auto_multiline(GeanyEditor *editor, gint pos); static void auto_close_chars(ScintillaObject *sci, gint pos, gchar c); static void close_block(GeanyEditor *editor, gint pos); static void editor_highlight_braces(GeanyEditor *editor, gint cur_pos); static void read_current_word(GeanyEditor *editor, gint pos, gchar *word, gsize wordlen, const gchar *wc, gboolean stem); static gsize count_indent_size(GeanyEditor *editor, const gchar *base_indent); static const gchar *snippets_find_completion_by_name(const gchar *type, const gchar *name); static void snippets_make_replacements(GeanyEditor *editor, GString *pattern); static GeanyFiletype *editor_get_filetype_at_line(GeanyEditor *editor, gint line); static gboolean sci_is_blank_line(ScintillaObject *sci, gint line); void editor_snippets_free(void) { g_hash_table_destroy(snippet_hash); gtk_window_remove_accel_group(GTK_WINDOW(main_widgets.window), snippet_accel_group); } static void snippets_load(GKeyFile *sysconfig, GKeyFile *userconfig) { gsize i, j, len = 0, len_keys = 0; gchar **groups_user, **groups_sys; gchar **keys_user, **keys_sys; gchar *value; GHashTable *tmp; /* keys are strings, values are GHashTables, so use g_free and g_hash_table_destroy */ snippet_hash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_hash_table_destroy); /* first read all globally defined auto completions */ groups_sys = g_key_file_get_groups(sysconfig, &len); for (i = 0; i < len; i++) { if (strcmp(groups_sys[i], "Keybindings") == 0) continue; keys_sys = g_key_file_get_keys(sysconfig, groups_sys[i], &len_keys, NULL); /* create new hash table for the read section (=> filetype) */ tmp = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); g_hash_table_insert(snippet_hash, g_strdup(groups_sys[i]), tmp); for (j = 0; j < len_keys; j++) { g_hash_table_insert(tmp, g_strdup(keys_sys[j]), utils_get_setting_string(sysconfig, groups_sys[i], keys_sys[j], "")); } g_strfreev(keys_sys); } g_strfreev(groups_sys); /* now read defined completions in user's configuration directory and add / replace them */ groups_user = g_key_file_get_groups(userconfig, &len); for (i = 0; i < len; i++) { if (strcmp(groups_user[i], "Keybindings") == 0) continue; keys_user = g_key_file_get_keys(userconfig, groups_user[i], &len_keys, NULL); tmp = g_hash_table_lookup(snippet_hash, groups_user[i]); if (tmp == NULL) { /* new key found, create hash table */ tmp = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); g_hash_table_insert(snippet_hash, g_strdup(groups_user[i]), tmp); } for (j = 0; j < len_keys; j++) { value = g_hash_table_lookup(tmp, keys_user[j]); if (value == NULL) { /* value = NULL means the key doesn't yet exist, so insert */ g_hash_table_insert(tmp, g_strdup(keys_user[j]), utils_get_setting_string(userconfig, groups_user[i], keys_user[j], "")); } else { /* old key and value will be freed by destroy function (g_free) */ g_hash_table_replace(tmp, g_strdup(keys_user[j]), utils_get_setting_string(userconfig, groups_user[i], keys_user[j], "")); } } g_strfreev(keys_user); } g_strfreev(groups_user); } static gboolean on_snippet_keybinding_activate(gchar *key) { GeanyDocument *doc = document_get_current(); const gchar *s; if (!doc || !gtk_widget_has_focus(GTK_WIDGET(doc->editor->sci))) return FALSE; s = snippets_find_completion_by_name(doc->file_type->name, key); if (!s) /* allow user to specify keybindings for "special" snippets */ { GHashTable *specials = g_hash_table_lookup(snippet_hash, "Special"); if (G_LIKELY(specials != NULL)) s = g_hash_table_lookup(specials, key); } if (!s) { utils_beep(); return FALSE; } editor_insert_snippet(doc->editor, sci_get_current_position(doc->editor->sci), s); sci_scroll_caret(doc->editor->sci); return TRUE; } static void add_kb(GKeyFile *keyfile, const gchar *group, gchar **keys) { gsize i; if (!keys) return; for (i = 0; i < g_strv_length(keys); i++) { guint key; GdkModifierType mods; gchar *accel_string = g_key_file_get_value(keyfile, group, keys[i], NULL); gtk_accelerator_parse(accel_string, &key, &mods); if (key == 0 && mods == 0) { g_warning("Can not parse accelerator \"%s\" from user snippets.conf", accel_string); g_free(accel_string); continue; } g_free(accel_string); gtk_accel_group_connect(snippet_accel_group, key, mods, 0, g_cclosure_new_swap((GCallback)on_snippet_keybinding_activate, g_strdup(keys[i]), (GClosureNotify)g_free)); } } static void load_kb(GKeyFile *sysconfig, GKeyFile *userconfig) { const gchar kb_group[] = "Keybindings"; gchar **keys = g_key_file_get_keys(userconfig, kb_group, NULL, NULL); gchar **ptr; /* remove overridden keys from system keyfile */ foreach_strv(ptr, keys) g_key_file_remove_key(sysconfig, kb_group, *ptr, NULL); add_kb(userconfig, kb_group, keys); g_strfreev(keys); keys = g_key_file_get_keys(sysconfig, kb_group, NULL, NULL); add_kb(sysconfig, kb_group, keys); g_strfreev(keys); } void editor_snippets_init(void) { gchar *sysconfigfile, *userconfigfile; GKeyFile *sysconfig = g_key_file_new(); GKeyFile *userconfig = g_key_file_new(); sysconfigfile = g_build_filename(app->datadir, "snippets.conf", NULL); userconfigfile = g_build_filename(app->configdir, "snippets.conf", NULL); /* check for old autocomplete.conf files (backwards compatibility) */ if (! g_file_test(userconfigfile, G_FILE_TEST_IS_REGULAR)) SETPTR(userconfigfile, g_build_filename(app->configdir, "autocomplete.conf", NULL)); /* load the actual config files */ g_key_file_load_from_file(sysconfig, sysconfigfile, G_KEY_FILE_NONE, NULL); g_key_file_load_from_file(userconfig, userconfigfile, G_KEY_FILE_NONE, NULL); snippets_load(sysconfig, userconfig); /* setup snippet keybindings */ snippet_accel_group = gtk_accel_group_new(); gtk_window_add_accel_group(GTK_WINDOW(main_widgets.window), snippet_accel_group); load_kb(sysconfig, userconfig); g_free(sysconfigfile); g_free(userconfigfile); g_key_file_free(sysconfig); g_key_file_free(userconfig); } static gboolean on_editor_button_press_event(GtkWidget *widget, GdkEventButton *event, gpointer data) { GeanyEditor *editor = data; GeanyDocument *doc = editor->document; /* it's very unlikely we got a 'real' click even on 0, 0, so assume it is a * fake event to show the editor menu triggered by a key event where we want to use the * text cursor position. */ if (event->x > 0.0 && event->y > 0.0) editor_info.click_pos = sci_get_position_from_xy(editor->sci, (gint)event->x, (gint)event->y, FALSE); else editor_info.click_pos = sci_get_current_position(editor->sci); if (event->button == 1) { guint state = keybindings_get_modifiers(event->state); if (event->type == GDK_BUTTON_PRESS && editor_prefs.disable_dnd) { gint ss = sci_get_selection_start(editor->sci); sci_set_selection_end(editor->sci, ss); } if (event->type == GDK_BUTTON_PRESS && state == GEANY_PRIMARY_MOD_MASK) { sci_set_current_position(editor->sci, editor_info.click_pos, FALSE); editor_find_current_word(editor, editor_info.click_pos, current_word, sizeof current_word, NULL); if (*current_word) return symbols_goto_tag(current_word, TRUE); else keybindings_send_command(GEANY_KEY_GROUP_GOTO, GEANY_KEYS_GOTO_MATCHINGBRACE); return TRUE; } return document_check_disk_status(doc, FALSE); } /* calls the edit popup menu in the editor */ if (event->button == 3) { gboolean can_goto; /* ensure the editor widget has the focus after this operation */ gtk_widget_grab_focus(widget); editor_find_current_word(editor, editor_info.click_pos, current_word, sizeof current_word, NULL); can_goto = sci_has_selection(editor->sci) || current_word[0] != '\0'; ui_update_popup_goto_items(can_goto); ui_update_popup_copy_items(doc); ui_update_insert_include_item(doc, 0); g_signal_emit_by_name(geany_object, "update-editor-menu", current_word, editor_info.click_pos, doc); gtk_menu_popup_at_pointer(GTK_MENU(main_widgets.editor_menu), (GdkEvent *) event); return TRUE; } return FALSE; } static gboolean is_style_php(gint style) { if ((style >= SCE_HPHP_DEFAULT && style <= SCE_HPHP_OPERATOR) || style == SCE_HPHP_COMPLEX_VARIABLE) { return TRUE; } return FALSE; } static gint editor_get_long_line_type(void) { if (app->project) switch (app->project->priv->long_line_behaviour) { case 0: /* marker disabled */ return 2; case 1: /* use global settings */ break; case 2: /* custom (enabled) */ return editor_prefs.long_line_type; } if (!editor_prefs.long_line_enabled) return 2; else return editor_prefs.long_line_type; } static gint editor_get_long_line_column(void) { if (app->project && app->project->priv->long_line_behaviour != 1 /* use global settings */) return app->project->priv->long_line_column; else return editor_prefs.long_line_column; } #define get_project_pref(id)\ (app->project ? app->project->priv->id : editor_prefs.id) static const GeanyEditorPrefs * get_default_prefs(void) { static GeanyEditorPrefs eprefs; eprefs = editor_prefs; /* project overrides */ eprefs.indentation = (GeanyIndentPrefs*)editor_get_indent_prefs(NULL); eprefs.long_line_type = editor_get_long_line_type(); eprefs.long_line_column = editor_get_long_line_column(); eprefs.line_wrapping = get_project_pref(line_wrapping); eprefs.line_break_column = get_project_pref(line_break_column); eprefs.auto_continue_multiline = get_project_pref(auto_continue_multiline); return &eprefs; } /* Gets the prefs for the editor. * Prefs can be different according to project or document. * @warning Always get a fresh result instead of keeping a pointer to it if the editor/project * settings may have changed, or if this function has been called for a different editor. * @param editor The editor, or @c NULL to get the default prefs. * @return The prefs. */ const GeanyEditorPrefs *editor_get_prefs(GeanyEditor *editor) { static GeanyEditorPrefs eprefs; const GeanyEditorPrefs *dprefs = get_default_prefs(); /* Return the address of the default prefs to allow returning default and editor * pref pointers without invalidating the contents of either. */ if (editor == NULL) return dprefs; eprefs = *dprefs; eprefs.indentation = (GeanyIndentPrefs*)editor_get_indent_prefs(editor); /* add other editor & document overrides as needed */ return &eprefs; } void editor_toggle_fold(GeanyEditor *editor, gint line, gint modifiers) { ScintillaObject *sci; gint header; g_return_if_fail(editor != NULL); sci = editor->sci; /* When collapsing a fold range whose starting line is offscreen, * scroll the starting line to display at the top of the view. * Otherwise it can be confusing when the document scrolls down to hide * the folded lines. */ if ((sci_get_fold_level(sci, line) & SC_FOLDLEVELNUMBERMASK) > SC_FOLDLEVELBASE && !(sci_get_fold_level(sci, line) & SC_FOLDLEVELHEADERFLAG)) { gint parent = sci_get_fold_parent(sci, line); gint first = sci_get_first_visible_line(sci); parent = SSM(sci, SCI_VISIBLEFROMDOCLINE, parent, 0); if (first > parent) SSM(sci, SCI_SETFIRSTVISIBLELINE, parent, 0); } /* find the fold header of the given line in case the one clicked isn't a fold point */ if (sci_get_fold_level(sci, line) & SC_FOLDLEVELHEADERFLAG) header = line; else header = sci_get_fold_parent(sci, line); if ((editor_prefs.unfold_all_children && ! (modifiers & SCMOD_SHIFT)) || (! editor_prefs.unfold_all_children && (modifiers & SCMOD_SHIFT))) { SSM(sci, SCI_FOLDCHILDREN, header, SC_FOLDACTION_TOGGLE); } else { SSM(sci, SCI_FOLDLINE, header, SC_FOLDACTION_TOGGLE); } } static void on_margin_click(GeanyEditor *editor, SCNotification *nt) { /* left click to marker margin marks the line */ if (nt->margin == 1) { gint line = sci_get_line_from_position(editor->sci, nt->position); /*sci_marker_delete_all(editor->sci, 1);*/ sci_toggle_marker_at_line(editor->sci, line, 1); /* toggle the marker */ } /* left click on the folding margin to toggle folding state of current line */ else if (nt->margin == 2 && editor_prefs.folding) { gint line = sci_get_line_from_position(editor->sci, nt->position); editor_toggle_fold(editor, line, nt->modifiers); } } static void on_update_ui(GeanyEditor *editor, G_GNUC_UNUSED SCNotification *nt) { ScintillaObject *sci = editor->sci; gint pos = sci_get_current_position(sci); /* since Scintilla 2.24, SCN_UPDATEUI is also sent on scrolling though we don't need to handle * this and so ignore every SCN_UPDATEUI events except for content and selection changes */ if (! (nt->updated & SC_UPDATE_CONTENT) && ! (nt->updated & SC_UPDATE_SELECTION)) return; /* undo / redo menu update */ ui_update_popup_reundo_items(editor->document); /* brace highlighting */ editor_highlight_braces(editor, pos); ui_update_statusbar(editor->document, pos); #if 0 /** experimental code for inverting selections */ { gint i; for (i = SSM(sci, SCI_GETSELECTIONSTART, 0, 0); i < SSM(sci, SCI_GETSELECTIONEND, 0, 0); i++) { /* need to get colour from getstyleat(), but how? */ SSM(sci, SCI_STYLESETFORE, STYLE_DEFAULT, 0); SSM(sci, SCI_STYLESETBACK, STYLE_DEFAULT, 0); } sci_get_style_at(sci, pos); } #endif } static void check_line_breaking(GeanyEditor *editor, gint pos) { ScintillaObject *sci = editor->sci; gint line, lstart, col; gchar c; if (!editor->line_breaking || sci_get_selection_mode(editor->sci) != SC_SEL_STREAM) return; col = sci_get_col_from_position(sci, pos); line = sci_get_current_line(sci); lstart = sci_get_position_from_line(sci, line); /* use column instead of position which might be different with multibyte characters */ if (col < get_project_pref(line_break_column)) return; /* look for the last space before line_break_column */ pos = sci_get_position_from_col(sci, line, get_project_pref(line_break_column)); while (pos > lstart) { c = sci_get_char_at(sci, --pos); if (c == ' ') { gint diff, last_pos, last_col; /* remember the distance between the current column and the last column on the line * (we use column position in case the previous line gets altered, such as removing * trailing spaces or in case it contains multibyte characters) */ last_pos = sci_get_line_end_position(sci, line); last_col = sci_get_col_from_position(sci, last_pos); diff = last_col - col; /* break the line after the space */ sci_set_current_position(sci, pos + 1, FALSE); sci_cancel(sci); /* don't select from completion list */ sci_send_command(sci, SCI_NEWLINE); line++; /* correct cursor position (might not be at line end) */ last_pos = sci_get_line_end_position(sci, line); last_col = sci_get_col_from_position(sci, last_pos); /* get last column on line */ /* last column - distance is the desired column, then retrieve its document position */ pos = sci_get_position_from_col(sci, line, last_col - diff); sci_set_current_position(sci, pos, FALSE); sci_scroll_caret(sci); return; } } } static void show_autocomplete(ScintillaObject *sci, gsize rootlen, GString *words) { /* hide autocompletion if only option is already typed */ if (rootlen >= words->len || (words->str[rootlen] == '?' && rootlen >= words->len - 2)) { sci_send_command(sci, SCI_AUTOCCANCEL); return; } /* store whether a calltip is showing, so we can reshow it after autocompletion */ calltip.set = (gboolean) SSM(sci, SCI_CALLTIPACTIVE, 0, 0); SSM(sci, SCI_AUTOCSETORDER, SC_ORDER_CUSTOM, 0); SSM(sci, SCI_AUTOCSHOW, rootlen, (sptr_t) words->str); } static void show_tags_list(GeanyEditor *editor, const GPtrArray *tags, gsize rootlen) { ScintillaObject *sci = editor->sci; g_return_if_fail(tags); if (tags->len > 0) { GString *words = g_string_sized_new(150); guint j; for (j = 0; j < tags->len; ++j) { TMTag *tag = tags->pdata[j]; gint group; guint icon_id; if (j > 0) g_string_append_c(words, '\n'); if (j == editor_prefs.autocompletion_max_entries) { g_string_append(words, "..."); break; } g_string_append(words, tag->name); group = tm_parser_get_sidebar_group(tag->lang, tag->type); if (group >= 0 && tm_parser_get_sidebar_info(tag->lang, group, &icon_id)) { gchar buf[10]; sprintf(buf, "?%u", icon_id + 1); g_string_append(words, buf); } } show_autocomplete(sci, rootlen, words); g_string_free(words, TRUE); } } static gint scope_autocomplete_suffix(ScintillaObject *sci, TMParserType lang, gint pos, gboolean *scope_sep) { const gchar *sep = tm_parser_scope_separator(lang); const gsize max_len = 3; gboolean is_scope_sep; gchar *buf; buf = g_alloca(max_len + 1); sci_get_text_range(sci, pos - max_len, pos, buf); is_scope_sep = g_str_has_suffix(buf, sep); if (scope_sep) *scope_sep = is_scope_sep; if (is_scope_sep) return strlen(sep); return tm_parser_scope_autocomplete_suffix(lang, buf); } static gboolean reshow_calltip(gpointer data) { GeanyDocument *doc; g_return_val_if_fail(calltip.sci != NULL, FALSE); SSM(calltip.sci, SCI_CALLTIPCANCEL, 0, 0); doc = document_get_current(); if (doc && doc->editor->sci == calltip.sci) { /* we use the position where the calltip was previously started as SCI_GETCURRENTPOS * may be completely wrong in case the user cancelled the auto completion with the mouse */ SSM(calltip.sci, SCI_CALLTIPSHOW, calltip.pos, (sptr_t) calltip.text); } return FALSE; } static void request_reshowing_calltip(SCNotification *nt) { if (calltip.set) { /* delay the reshow of the calltip window to make sure it is actually displayed, * without it might be not visible on SCN_AUTOCCANCEL. the priority is set to * low to hopefully make Scintilla's events happen before reshowing since they * seem to re-cancel the calltip on autoc menu hiding too */ g_idle_add_full(G_PRIORITY_LOW, reshow_calltip, NULL, NULL); } } static gboolean autocomplete_scope(GeanyEditor *editor, const gchar *root, gsize rootlen) { ScintillaObject *sci = editor->sci; gint pos = sci_get_current_position(editor->sci); gint line = sci_get_current_line(editor->sci) + 1; gchar brace_char; gchar *name; GeanyFiletype *ft = editor->document->file_type; GPtrArray *tags; gboolean function = FALSE; gboolean member; gboolean scope_sep_typed = FALSE; gboolean ret = FALSE; const gchar *current_scope; gint autocomplete_suffix_len; if (autocomplete_scope_shown) { /* move at the operator position */ pos -= rootlen; /* allow for a space between word and operator */ while (pos > 0 && isspace(sci_get_char_at(sci, pos - 1))) pos--; } autocomplete_suffix_len = scope_autocomplete_suffix(sci, ft->lang, pos, &scope_sep_typed); if (autocomplete_suffix_len == 0) return FALSE; pos -= autocomplete_suffix_len; /* allow for a space between word and operator */ while (pos > 0 && isspace(sci_get_char_at(sci, pos - 1))) pos--; /* if function or array index, skip to matching brace */ brace_char = sci_get_char_at(sci, pos - 1); if (pos > 0 && (brace_char == ')' || brace_char == ']')) { gint brace_pos = sci_find_matching_brace(sci, pos - 1); if (brace_pos != -1) { pos = brace_pos; function = brace_char == ')'; } /* allow for a space between opening brace and name */ while (pos > 0 && isspace(sci_get_char_at(sci, pos - 1))) pos--; } name = editor_get_word_at_pos(editor, pos, NULL); if (!name) return FALSE; /* check if invoked on member */ pos -= strlen(name); while (pos > 0 && isspace(sci_get_char_at(sci, pos - 1))) pos--; member = scope_autocomplete_suffix(sci, ft->lang, pos, NULL) > 0; if (symbols_get_current_scope(editor->document, ¤t_scope) == -1) current_scope = ""; tags = tm_workspace_find_scope_members(editor->document->tm_file, name, function, member, current_scope, line, scope_sep_typed); if (tags) { GPtrArray *filtered = g_ptr_array_new(); TMTag *tag; guint i; foreach_ptr_array(tag, i, tags) { if (g_str_has_prefix(tag->name, root)) g_ptr_array_add(filtered, tag); } if (filtered->len > 0) { show_tags_list(editor, filtered, rootlen); ret = TRUE; } g_ptr_array_free(tags, TRUE); g_ptr_array_free(filtered, TRUE); } g_free(name); return ret; } static void on_char_added(GeanyEditor *editor, SCNotification *nt) { ScintillaObject *sci = editor->sci; gint pos = sci_get_current_position(sci); switch (nt->ch) { case '\r': { /* simple indentation (only for CR format) */ if (sci_get_eol_mode(sci) == SC_EOL_CR) on_new_line_added(editor); break; } case '\n': { /* simple indentation (for CR/LF and LF format) */ on_new_line_added(editor); break; } case '>': editor_start_auto_complete(editor, pos, FALSE); /* C/C++ ptr-> scope completion */ /* fall through */ case '/': { /* close xml-tags */ handle_xml(editor, pos, nt->ch); break; } case '(': { auto_close_chars(sci, pos, nt->ch); /* show calltips */ editor_show_calltip(editor, --pos); break; } case ')': { /* hide calltips */ if (SSM(sci, SCI_CALLTIPACTIVE, 0, 0)) { SSM(sci, SCI_CALLTIPCANCEL, 0, 0); } g_free(calltip.text); calltip.text = NULL; calltip.pos = 0; calltip.sci = NULL; calltip.set = FALSE; break; } case '{': case '[': case '"': case '\'': { auto_close_chars(sci, pos, nt->ch); break; } case '}': { /* closing bracket handling */ if (editor->auto_indent) close_block(editor, pos - 1); break; } /* scope autocompletion */ case '.': case ':': /* C/C++ class:: syntax */ /* tag autocompletion */ default: #if 0 if (! editor_start_auto_complete(editor, pos, FALSE)) request_reshowing_calltip(nt); #else editor_start_auto_complete(editor, pos, FALSE); #endif } check_line_breaking(editor, pos); } /* expand() and fold_changed() are copied from SciTE (thanks) to fix #1923350. */ static void expand(ScintillaObject *sci, gint *line, gboolean doExpand, gboolean force, gint visLevels, gint level) { gint lineMaxSubord = SSM(sci, SCI_GETLASTCHILD, *line, level & SC_FOLDLEVELNUMBERMASK); gint levelLine = level; (*line)++; while (*line <= lineMaxSubord) { if (force) { if (visLevels > 0) SSM(sci, SCI_SHOWLINES, *line, *line); else SSM(sci, SCI_HIDELINES, *line, *line); } else { if (doExpand) SSM(sci, SCI_SHOWLINES, *line, *line); } if (levelLine == -1) levelLine = SSM(sci, SCI_GETFOLDLEVEL, *line, 0); if (levelLine & SC_FOLDLEVELHEADERFLAG) { if (force) { if (visLevels > 1) SSM(sci, SCI_SETFOLDEXPANDED, *line, 1); else SSM(sci, SCI_SETFOLDEXPANDED, *line, 0); expand(sci, line, doExpand, force, visLevels - 1, -1); } else { if (doExpand) { if (!sci_get_fold_expanded(sci, *line)) SSM(sci, SCI_SETFOLDEXPANDED, *line, 1); expand(sci, line, TRUE, force, visLevels - 1, -1); } else { expand(sci, line, FALSE, force, visLevels - 1, -1); } } } else { (*line)++; } } } static void fold_changed(ScintillaObject *sci, gint line, gint levelNow, gint levelPrev) { if (levelNow & SC_FOLDLEVELHEADERFLAG) { if (! (levelPrev & SC_FOLDLEVELHEADERFLAG)) { /* Adding a fold point */ SSM(sci, SCI_SETFOLDEXPANDED, line, 1); if (!SSM(sci, SCI_GETALLLINESVISIBLE, 0, 0)) expand(sci, &line, TRUE, FALSE, 0, levelPrev); } } else if (levelPrev & SC_FOLDLEVELHEADERFLAG) { if (! sci_get_fold_expanded(sci, line)) { /* Removing the fold from one that has been contracted so should expand * otherwise lines are left invisible with no way to make them visible */ SSM(sci, SCI_SETFOLDEXPANDED, line, 1); if (!SSM(sci, SCI_GETALLLINESVISIBLE, 0, 0)) expand(sci, &line, TRUE, FALSE, 0, levelPrev); } } if (! (levelNow & SC_FOLDLEVELWHITEFLAG) && ((levelPrev & SC_FOLDLEVELNUMBERMASK) > (levelNow & SC_FOLDLEVELNUMBERMASK))) { if (!SSM(sci, SCI_GETALLLINESVISIBLE, 0, 0)) { /* See if should still be hidden */ gint parentLine = sci_get_fold_parent(sci, line); if (parentLine < 0) { SSM(sci, SCI_SHOWLINES, line, line); } else if (sci_get_fold_expanded(sci, parentLine) && sci_get_line_is_visible(sci, parentLine)) { SSM(sci, SCI_SHOWLINES, line, line); } } } } static void ensure_range_visible(ScintillaObject *sci, gint posStart, gint posEnd, gboolean enforcePolicy) { gint lineStart = sci_get_line_from_position(sci, MIN(posStart, posEnd)); gint lineEnd = sci_get_line_from_position(sci, MAX(posStart, posEnd)); gint line; for (line = lineStart; line <= lineEnd; line++) { SSM(sci, enforcePolicy ? SCI_ENSUREVISIBLEENFORCEPOLICY : SCI_ENSUREVISIBLE, line, 0); } } static void auto_update_margin_width(GeanyEditor *editor) { gint next_linecount = 1; gint linecount = sci_get_line_count(editor->sci); GeanyDocument *doc = editor->document; while (next_linecount <= linecount) next_linecount *= 10; if (editor->document->priv->line_count != next_linecount) { doc->priv->line_count = next_linecount; sci_set_line_numbers(editor->sci, TRUE); } } static void partial_complete(ScintillaObject *sci, const gchar *text) { gint pos = sci_get_current_position(sci); sci_insert_text(sci, pos, text); sci_set_current_position(sci, pos + strlen(text), TRUE); } /* Complete the next word part from @a entry */ static gboolean check_partial_completion(GeanyEditor *editor, const gchar *entry) { gchar *stem, *ptr, *text = utils_strdupa(entry); read_current_word(editor, -1, current_word, sizeof current_word, NULL, TRUE); stem = current_word; if (strstr(text, stem) != text) return FALSE; /* shouldn't happen */ if (strlen(text) <= strlen(stem)) return FALSE; text += strlen(stem); /* skip stem */ ptr = strstr(text + 1, "_"); if (ptr) { ptr[1] = '\0'; partial_complete(editor->sci, text); return TRUE; } else { /* CamelCase */ foreach_str(ptr, text + 1) { if (!ptr[0]) break; if (g_ascii_isupper(*ptr) && g_ascii_islower(ptr[1])) { ptr[0] = '\0'; partial_complete(editor->sci, text); return TRUE; } } } return FALSE; } /* Callback for the "sci-notify" signal to emit a "editor-notify" signal. * Plugins can connect to the "editor-notify" signal. */ void editor_sci_notify_cb(G_GNUC_UNUSED GtkWidget *widget, G_GNUC_UNUSED gint scn, gpointer scnt, gpointer data) { GeanyEditor *editor = data; gboolean retval; g_return_if_fail(editor != NULL); g_signal_emit_by_name(geany_object, "editor-notify", editor, scnt, &retval); } /* recalculate margins width */ static void update_margins(ScintillaObject *sci) { sci_set_line_numbers(sci, editor_prefs.show_linenumber_margin); sci_set_symbol_margin(sci, editor_prefs.show_markers_margin); sci_set_folding_margin_visible(sci, editor_prefs.folding); } static gboolean on_editor_notify(G_GNUC_UNUSED GObject *object, GeanyEditor *editor, SCNotification *nt, G_GNUC_UNUSED gpointer data) { ScintillaObject *sci = editor->sci; GeanyDocument *doc = editor->document; switch (nt->nmhdr.code) { case SCN_SAVEPOINTLEFT: document_set_text_changed(doc, TRUE); break; case SCN_SAVEPOINTREACHED: document_set_text_changed(doc, FALSE); break; case SCN_MODIFYATTEMPTRO: utils_beep(); break; case SCN_MARGINCLICK: on_margin_click(editor, nt); break; case SCN_UPDATEUI: on_update_ui(editor, nt); break; case SCN_PAINTED: /* Visible lines are only laid out accurately just before painting, * so we need to only call editor_scroll_to_line here, because the document * may have line wrapping and folding enabled. * https://scintilla.sourceforge.io/ScintillaDoc.html#LineWrapping * This is important e.g. when loading a session and switching pages * and having the cursor scroll in view. */ /* FIXME: Really we want to do this just before painting, not after it * as it will cause repainting. */ if (editor->scroll_percent > 0.0F) { editor_scroll_to_line(editor, -1, editor->scroll_percent); /* disable further scrolling */ editor->scroll_percent = -1.0F; } break; case SCN_MODIFIED: if (editor_prefs.show_linenumber_margin && (nt->modificationType & (SC_MOD_INSERTTEXT | SC_MOD_DELETETEXT)) && nt->linesAdded) { /* automatically adjust Scintilla's line numbers margin width */ auto_update_margin_width(editor); } if (nt->modificationType & SC_STARTACTION && ! ignore_callback) { /* get notified about undo changes */ document_undo_add(doc, UNDO_SCINTILLA, NULL); } if (editor_prefs.folding && (nt->modificationType & SC_MOD_CHANGEFOLD) != 0) { /* handle special fold cases, e.g. #1923350 */ fold_changed(sci, nt->line, nt->foldLevelNow, nt->foldLevelPrev); } if (nt->modificationType & (SC_MOD_INSERTTEXT | SC_MOD_DELETETEXT)) { document_update_tag_list_in_idle(doc); } break; case SCN_CHARADDED: on_char_added(editor, nt); break; case SCN_USERLISTSELECTION: if (nt->listType == 1) { sci_add_text(sci, nt->text); } break; case SCN_AUTOCSELECTION: if (g_str_equal(nt->text, "...")) { sci_cancel(sci); utils_beep(); break; } /* fall through */ case SCN_AUTOCCANCELLED: /* now that autocomplete is finishing or was cancelled, reshow calltips * if they were showing */ autocomplete_scope_shown = FALSE; request_reshowing_calltip(nt); break; case SCN_NEEDSHOWN: ensure_range_visible(sci, nt->position, nt->position + nt->length, FALSE); break; case SCN_URIDROPPED: if (nt->text != NULL) { document_open_file_list(nt->text, strlen(nt->text)); } break; case SCN_CALLTIPCLICK: if (nt->position > 0) { switch (nt->position) { case 1: /* up arrow */ if (calltip.tag_index > 0) calltip.tag_index--; break; case 2: calltip.tag_index++; break; /* down arrow */ } editor_show_calltip(editor, -1); } break; case SCN_ZOOM: update_margins(sci); break; } /* we always return FALSE here to let plugins handle the event too */ return FALSE; } /* Note: this is the same as sci_get_tab_width(), but is still useful when you don't have * a scintilla pointer. */ static gint get_tab_width(const GeanyIndentPrefs *indent_prefs) { if (indent_prefs->type == GEANY_INDENT_TYPE_BOTH) return indent_prefs->hard_tab_width; return indent_prefs->width; /* tab width = indent width */ } /* Returns a string containing width chars of whitespace, filled with simple space * characters or with the right number of tab characters, according to the indent prefs. * (Result is filled with tabs *and* spaces if width isn't a multiple of * the tab width). */ static gchar * get_whitespace(const GeanyIndentPrefs *iprefs, gint width) { g_return_val_if_fail(width >= 0, NULL); if (width == 0) return g_strdup(""); if (iprefs->type == GEANY_INDENT_TYPE_SPACES) { return g_strnfill(width, ' '); } else { /* first fill text with tabs and fill the rest with spaces */ const gint tab_width = get_tab_width(iprefs); gint tabs = width / tab_width; gint spaces = width % tab_width; gint len = tabs + spaces; gchar *str; str = g_malloc(len + 1); memset(str, '\t', tabs); memset(str + tabs, ' ', spaces); str[len] = '\0'; return str; } } static const GeanyIndentPrefs * get_default_indent_prefs(void) { static GeanyIndentPrefs iprefs; iprefs = app->project ? *app->project->priv->indentation : *editor_prefs.indentation; return &iprefs; } /** Gets the indentation prefs for the editor. * Prefs can be different according to project or document. * @warning Always get a fresh result instead of keeping a pointer to it if the editor/project * settings may have changed, or if this function has been called for a different editor. * @param editor @nullable The editor, or @c NULL to get the default indent prefs. * @return The indent prefs. */ GEANY_API_SYMBOL const GeanyIndentPrefs * editor_get_indent_prefs(GeanyEditor *editor) { static GeanyIndentPrefs iprefs; const GeanyIndentPrefs *dprefs = get_default_indent_prefs(); /* Return the address of the default prefs to allow returning default and editor * pref pointers without invalidating the contents of either. */ if (editor == NULL) return dprefs; iprefs = *dprefs; iprefs.type = editor->indent_type; iprefs.width = editor->indent_width; /* if per-document auto-indent is enabled, but we don't have a global mode set, * just use basic auto-indenting */ if (editor->auto_indent && iprefs.auto_indent_mode == GEANY_AUTOINDENT_NONE) iprefs.auto_indent_mode = GEANY_AUTOINDENT_BASIC; if (!editor->auto_indent) iprefs.auto_indent_mode = GEANY_AUTOINDENT_NONE; return &iprefs; } static void on_new_line_added(GeanyEditor *editor) { ScintillaObject *sci = editor->sci; gint line = sci_get_current_line(sci); /* simple indentation */ if (editor->auto_indent) { insert_indent_after_line(editor, line - 1); } if (get_project_pref(auto_continue_multiline)) { /* " * " auto completion in multiline C/C++/D/Java comments */ auto_multiline(editor, line); } if (editor_prefs.newline_strip) { /* strip the trailing spaces on the previous line */ editor_strip_line_trailing_spaces(editor, line - 1); } } static gboolean lexer_has_braces(ScintillaObject *sci) { gint lexer = sci_get_lexer(sci); switch (lexer) { case SCLEX_CPP: case SCLEX_D: case SCLEX_HTML: /* for PHP & JS */ case SCLEX_PHPSCRIPT: case SCLEX_PASCAL: /* for multiline comments? */ case SCLEX_BASH: case SCLEX_PERL: case SCLEX_TCL: case SCLEX_R: case SCLEX_RUST: return TRUE; default: return FALSE; } } /* Read indent chars for the line that pos is on into indent global variable. * Note: Use sci_get_line_indentation() and get_whitespace()/editor_insert_text_block() * instead in any new code. */ static void read_indent(GeanyEditor *editor, gint pos) { ScintillaObject *sci = editor->sci; guint i, len, j = 0; gint line; gchar *linebuf; line = sci_get_line_from_position(sci, pos); len = sci_get_line_length(sci, line); linebuf = sci_get_line(sci, line); for (i = 0; i < len && j <= (sizeof(indent) - 1); i++) { if (linebuf[i] == ' ' || linebuf[i] == '\t') /* simple indentation */ indent[j++] = linebuf[i]; else break; } indent[j] = '\0'; g_free(linebuf); } static gint get_brace_indent(ScintillaObject *sci, gint line) { gint start = sci_get_position_from_line(sci, line); gint end = sci_get_line_end_position(sci, line) - 1; gint lexer = sci_get_lexer(sci); gint count = 0; gint pos; for (pos = end; pos >= start && count < 1; pos--) { if (highlighting_is_code_style(lexer, sci_get_style_at(sci, pos))) { gchar c = sci_get_char_at(sci, pos); if (c == '{') count ++; else if (c == '}') count --; } } return count > 0 ? 1 : 0; } /* gets the last code position on a line * warning: if there is no code position on the line, returns the start position */ static gint get_sci_line_code_end_position(ScintillaObject *sci, gint line) { gint start = sci_get_position_from_line(sci, line); gint lexer = sci_get_lexer(sci); gint pos; for (pos = sci_get_line_end_position(sci, line) - 1; pos > start; pos--) { gint style = sci_get_style_at(sci, pos); if (highlighting_is_code_style(lexer, style) && ! isspace(sci_get_char_at(sci, pos))) break; } return pos; } static gint get_python_indent(ScintillaObject *sci, gint line) { gint last_char = get_sci_line_code_end_position(sci, line); /* add extra indentation for Python after colon */ if (sci_get_char_at(sci, last_char) == ':' && sci_get_style_at(sci, last_char) == SCE_P_OPERATOR) { return 1; } return 0; } static gint get_xml_indent(ScintillaObject *sci, gint line) { gboolean need_close = FALSE; gint end = get_sci_line_code_end_position(sci, line); gint pos; /* don't indent if there's a closing tag to the right of the cursor */ pos = sci_get_current_position(sci); if (sci_get_char_at(sci, pos) == '<' && sci_get_char_at(sci, pos + 1) == '/') return 0; if (sci_get_char_at(sci, end) == '>' && sci_get_char_at(sci, end - 1) != '/') { gint style = sci_get_style_at(sci, end); if (style == SCE_H_TAG || style == SCE_H_TAGUNKNOWN) { gint start = sci_get_position_from_line(sci, line); gchar *line_contents = sci_get_contents_range(sci, start, end + 1); gchar *opened_tag_name = utils_find_open_xml_tag(line_contents, end + 1 - start); if (!EMPTY(opened_tag_name)) { need_close = TRUE; if (sci_get_lexer(sci) == SCLEX_HTML && utils_is_short_html_tag(opened_tag_name)) need_close = FALSE; } g_free(line_contents); g_free(opened_tag_name); } } return need_close ? 1 : 0; } static gint get_indent_size_after_line(GeanyEditor *editor, gint line) { ScintillaObject *sci = editor->sci; gint size; const GeanyIndentPrefs *iprefs = editor_get_indent_prefs(editor); g_return_val_if_fail(line >= 0, 0); size = sci_get_line_indentation(sci, line); if (iprefs->auto_indent_mode > GEANY_AUTOINDENT_BASIC) { gint additional_indent = 0; if (lexer_has_braces(sci)) additional_indent = iprefs->width * get_brace_indent(sci, line); else if (sci_get_lexer(sci) == SCLEX_PYTHON) /* Python/Cython */ additional_indent = iprefs->width * get_python_indent(sci, line); /* HTML lexer "has braces" because of PHP and JavaScript. If get_brace_indent() did not * recommend us to insert additional indent, we are probably not in PHP/JavaScript chunk and * should make the XML-related check */ if (additional_indent == 0 && (sci_get_lexer(sci) == SCLEX_HTML || sci_get_lexer(sci) == SCLEX_XML) && editor->document->file_type->priv->xml_indent_tags) { size += iprefs->width * get_xml_indent(sci, line); } size += additional_indent; } return size; } static void insert_indent_after_line(GeanyEditor *editor, gint line) { ScintillaObject *sci = editor->sci; gint line_indent = sci_get_line_indentation(sci, line); gint size = get_indent_size_after_line(editor, line); const GeanyIndentPrefs *iprefs = editor_get_indent_prefs(editor); gchar *text; if (size == 0) return; if (iprefs->type == GEANY_INDENT_TYPE_TABS && size == line_indent) { /* support tab indents, space aligns style - copy last line 'indent' exactly */ gint start = sci_get_position_from_line(sci, line); gint end = sci_get_line_indent_position(sci, line); text = sci_get_contents_range(sci, start, end); } else { text = get_whitespace(iprefs, size); } sci_add_text(sci, text); g_free(text); } static void auto_close_chars(ScintillaObject *sci, gint pos, gchar c) { const gchar *closing_char = NULL; gint end_pos = -1; if (utils_isbrace(c, 0)) end_pos = sci_find_matching_brace(sci, pos - 1); switch (c) { case '(': if ((editor_prefs.autoclose_chars & GEANY_AC_PARENTHESIS) && end_pos == -1) closing_char = ")"; break; case '{': if ((editor_prefs.autoclose_chars & GEANY_AC_CBRACKET) && end_pos == -1) closing_char = "}"; break; case '[': if ((editor_prefs.autoclose_chars & GEANY_AC_SBRACKET) && end_pos == -1) closing_char = "]"; break; case '\'': if (editor_prefs.autoclose_chars & GEANY_AC_SQUOTE) closing_char = "'"; break; case '"': if (editor_prefs.autoclose_chars & GEANY_AC_DQUOTE) closing_char = "\""; break; } if (closing_char != NULL) { sci_add_text(sci, closing_char); sci_set_current_position(sci, pos, TRUE); } } /* Finds a corresponding matching brace to the given pos * (this is taken from Scintilla Editor.cxx, * fit to work with close_block) */ static gint brace_match(ScintillaObject *sci, gint pos) { gchar chBrace = sci_get_char_at(sci, pos); gchar chSeek = utils_brace_opposite(chBrace); gchar chAtPos; gint direction = -1; gint styBrace; gint depth = 1; gint styAtPos; /* Hack: we need the style at @p pos but it isn't computed yet, so force styling * of this very position */ sci_colourise(sci, pos, pos + 1); styBrace = sci_get_style_at(sci, pos); if (utils_is_opening_brace(chBrace, editor_prefs.brace_match_ltgt)) direction = 1; pos += direction; while ((pos >= 0) && (pos < sci_get_length(sci))) { chAtPos = sci_get_char_at(sci, pos); styAtPos = sci_get_style_at(sci, pos); if ((pos > sci_get_end_styled(sci)) || (styAtPos == styBrace)) { if (chAtPos == chBrace) depth++; if (chAtPos == chSeek) depth--; if (depth == 0) return pos; } pos += direction; } return -1; } /* Called after typing '}'. */ static void close_block(GeanyEditor *editor, gint pos) { const GeanyIndentPrefs *iprefs = editor_get_indent_prefs(editor); gint x = 0, cnt = 0; gint line, line_len; gchar *line_buf; ScintillaObject *sci; gint line_indent, last_indent; if (iprefs->auto_indent_mode < GEANY_AUTOINDENT_CURRENTCHARS) return; g_return_if_fail(editor != NULL && editor->document->file_type != NULL); sci = editor->sci; if (! lexer_has_braces(sci)) return; line = sci_get_line_from_position(sci, pos); line_len = sci_get_line_end_position(sci, line) - sci_get_position_from_line(sci, line); /* check that the line is empty, to not kill text in the line */ line_buf = sci_get_line(sci, line); line_buf[line_len] = '\0'; while (x < line_len) { if (isspace(line_buf[x])) cnt++; x++; } g_free(line_buf); if ((line_len - 1) != cnt) return; if (iprefs->auto_indent_mode == GEANY_AUTOINDENT_MATCHBRACES) { gint start_brace = brace_match(sci, pos); if (start_brace >= 0) { gint line_start; gint brace_line = sci_get_line_from_position(sci, start_brace); gint size = sci_get_line_indentation(sci, brace_line); gchar *ind = get_whitespace(iprefs, size); gchar *text = g_strconcat(ind, "}", NULL); line_start = sci_get_position_from_line(sci, line); sci_set_anchor(sci, line_start); sci_replace_sel(sci, text); g_free(text); g_free(ind); return; } /* fall through - unmatched brace (possibly because of TCL, PHP lexer bugs) */ } /* GEANY_AUTOINDENT_CURRENTCHARS */ line_indent = sci_get_line_indentation(sci, line); last_indent = sci_get_line_indentation(sci, line - 1); if (line_indent < last_indent) return; line_indent -= iprefs->width; line_indent = MAX(0, line_indent); sci_set_line_indentation(sci, line, line_indent); } /* checks whether @p c is an ASCII character (e.g. < 0x80) */ #define IS_ASCII(c) (((unsigned char)(c)) < 0x80) /* Reads the word at given cursor position and writes it into the given buffer. The buffer will be * NULL terminated in any case, even when the word is truncated because wordlen is too small. * position can be -1, then the current position is used. * wc are the wordchars to use, if NULL, GEANY_WORDCHARS will be used */ static void read_current_word(GeanyEditor *editor, gint pos, gchar *word, gsize wordlen, const gchar *wc, gboolean stem) { gint line, line_start, startword, endword; gchar *chunk; ScintillaObject *sci; g_return_if_fail(editor != NULL); sci = editor->sci; if (pos == -1) pos = sci_get_current_position(sci); line = sci_get_line_from_position(sci, pos); line_start = sci_get_position_from_line(sci, line); startword = pos - line_start; endword = pos - line_start; word[0] = '\0'; chunk = sci_get_line(sci, line); if (wc == NULL) wc = GEANY_WORDCHARS; /* the checks for "c < 0" are to allow any Unicode character which should make the code * a little bit more Unicode safe, anyway, this allows also any Unicode punctuation, * TODO: improve this code */ while (startword > 0 && (strchr(wc, chunk[startword - 1]) || ! IS_ASCII(chunk[startword - 1]))) startword--; if (!stem) { while (chunk[endword] != 0 && (strchr(wc, chunk[endword]) || ! IS_ASCII(chunk[endword]))) endword++; } if (startword != endword) { chunk[endword] = '\0'; g_strlcpy(word, chunk + startword, wordlen); /* ensure null terminated */ } else g_strlcpy(word, "", wordlen); g_free(chunk); } /* Reads the word at given cursor position and writes it into the given buffer. The buffer will be * NULL terminated in any case, even when the word is truncated because wordlen is too small. * position can be -1, then the current position is used. * wc are the wordchars to use, if NULL, GEANY_WORDCHARS will be used */ void editor_find_current_word(GeanyEditor *editor, gint pos, gchar *word, gsize wordlen, const gchar *wc) { read_current_word(editor, pos, word, wordlen, wc, FALSE); } /* Same as editor_find_current_word() but uses editor's word boundaries to decide what the word * is. This should be used e.g. to get the word to search for */ void editor_find_current_word_sciwc(GeanyEditor *editor, gint pos, gchar *word, gsize wordlen) { gint start; gint end; g_return_if_fail(editor != NULL); if (pos == -1) pos = sci_get_current_position(editor->sci); start = sci_word_start_position(editor->sci, pos, TRUE); end = sci_word_end_position(editor->sci, pos, TRUE); if (start == end) /* caret in whitespaces sequence */ *word = 0; else { if ((guint)(end - start) >= wordlen) end = start + (wordlen - 1); sci_get_text_range(editor->sci, start, end, word); } } /** * Finds the word at the position specified by @a pos. If any word is found, it is returned. * Otherwise NULL is returned. * Additional wordchars can be specified to define what to consider as a word. * * @param editor The editor to operate on. * @param pos The position where the word should be read from. * May be @c -1 to use the current position. * @param wordchars The wordchars to separate words. wordchars mean all characters to count * as part of a word. May be @c NULL to use the default wordchars, * see @ref GEANY_WORDCHARS. * * @return @nullable A newly-allocated string containing the word at the given @a pos or @c NULL. * Should be freed when no longer needed. * * @since 0.16 */ GEANY_API_SYMBOL gchar *editor_get_word_at_pos(GeanyEditor *editor, gint pos, const gchar *wordchars) { static gchar cword[GEANY_MAX_WORD_LENGTH]; g_return_val_if_fail(editor != NULL, FALSE); read_current_word(editor, pos, cword, sizeof(cword), wordchars, FALSE); return (*cword == '\0') ? NULL : g_strdup(cword); } /* Read the word up to position @a pos. */ static const gchar * editor_read_word_stem(GeanyEditor *editor, gint pos, const gchar *wordchars) { static gchar word[GEANY_MAX_WORD_LENGTH]; read_current_word(editor, pos, word, sizeof word, wordchars, TRUE); return (*word) ? word : NULL; } static gint find_previous_brace(ScintillaObject *sci, gint pos) { gint orig_pos = pos; while (pos >= 0 && pos > orig_pos - 300) { gchar c = sci_get_char_at(sci, pos); if (utils_is_opening_brace(c, editor_prefs.brace_match_ltgt)) return pos; pos--; } return -1; } static gint find_start_bracket(ScintillaObject *sci, gint pos) { gint brackets = 0; gint orig_pos = pos; while (pos > 0 && pos > orig_pos - 300) { gchar c = sci_get_char_at(sci, pos); if (c == ')') brackets++; else if (c == '(') brackets--; if (brackets < 0) return pos; /* found start bracket */ pos--; } return -1; } static GPtrArray *get_constructor_tags(GeanyFiletype *ft, TMTag *tag, const gchar *constructor_method) { if (constructor_method && (tag->type == tm_tag_class_t || tag->type == tm_tag_struct_t)) { const TMTagType arg_types = tm_tag_function_t | tm_tag_prototype_t | tm_tag_method_t | tm_tag_macro_with_arg_t; const gchar *scope_sep = tm_parser_scope_separator(ft->lang); gchar *scope = EMPTY(tag->scope) ? g_strdup(tag->name) : g_strjoin(scope_sep, tag->scope, tag->name, NULL); GPtrArray *constructor_tags; constructor_tags = tm_workspace_find(constructor_method, scope, arg_types, NULL, ft->lang); g_free(scope); if (constructor_tags->len != 0) { /* found constructor tag, so use it instead of the class tag */ return constructor_tags; } else { g_ptr_array_free(constructor_tags, TRUE); } } return NULL; } static void update_tag_name_and_scope_for_calltip(const gchar *word, TMTag *tag, const gchar *constructor_method, const gchar **tag_name, const gchar **scope) { if (tag_name == NULL || scope == NULL) return; /* Remove scope and replace name with the current calltip word if the current tag * is the constructor method of the current calltip word, e.g. for Python: * "SomeClass.__init__ (self, arg1, ...)" will be changed to "SomeClass (self, arg1, ...)" */ if (constructor_method && utils_str_equal(constructor_method, tag->name) && !utils_str_equal(word, tag->name)) { *tag_name = word; *scope = NULL; } } static gchar *find_calltip(const gchar *word, GeanyFiletype *ft) { const gchar *constructor_method; GPtrArray *tags; TMTag *tag; GString *str = NULL; guint i; g_return_val_if_fail(ft && word && *word, NULL); /* use all types in case language uses wrong tag type e.g. python "members" instead of "methods" */ tags = tm_workspace_find(word, NULL, tm_tag_max_t, NULL, ft->lang); if (tags->len == 0) { g_ptr_array_free(tags, TRUE); return NULL; } tag = TM_TAG(tags->pdata[0]); /* user typed e.g. 'a = Classname(' in Python so lookup __init__() arguments */ constructor_method = tm_parser_get_constructor_method(tag->lang); if (constructor_method) { GPtrArray *constructor_tags = get_constructor_tags(ft, tag, constructor_method); if (constructor_tags) { g_ptr_array_free(tags, TRUE); tags = constructor_tags; } } /* remove tags with no argument list */ for (i = 0; i < tags->len; i++) { tag = TM_TAG(tags->pdata[i]); if (! tag->arglist) tags->pdata[i] = NULL; } tm_tags_prune((GPtrArray *) tags); if (tags->len == 0) { g_ptr_array_free(tags, TRUE); return NULL; } else { /* remove duplicate calltips */ TMTagAttrType sort_attr[] = {tm_tag_attr_name_t, tm_tag_attr_scope_t, tm_tag_attr_arglist_t, 0}; tm_tags_sort((GPtrArray *) tags, sort_attr, TRUE, FALSE); } /* if the current word has changed since last time, start with the first tag match */ if (! utils_str_equal(word, calltip.last_word)) calltip.tag_index = 0; /* cache the current word for next time */ g_free(calltip.last_word); calltip.last_word = g_strdup(word); calltip.tag_index = MIN(calltip.tag_index, tags->len - 1); /* ensure tag_index is in range */ for (i = calltip.tag_index; i < tags->len; i++) { tag = TM_TAG(tags->pdata[i]); if (str == NULL) { const gchar *tag_name = tag->name; const gchar *scope = tag->scope; gchar *f; update_tag_name_and_scope_for_calltip(word, tag, constructor_method, &tag_name, &scope); f = tm_parser_format_function(tag->lang, tag_name, tag->arglist, tag->var_type, scope); str = g_string_new(NULL); if (calltip.tag_index > 0) g_string_prepend(str, "\001 "); /* up arrow */ g_string_append(str, f); g_free(f); } else /* add a down arrow */ { if (calltip.tag_index > 0) /* already have an up arrow */ g_string_insert_c(str, 1, '\002'); else g_string_prepend(str, "\002 "); break; } } g_ptr_array_free(tags, TRUE); if (str) { gchar *result = str->str; g_string_free(str, FALSE); return result; } return NULL; } /* use pos = -1 to search for the previous unmatched open bracket. */ gboolean editor_show_calltip(GeanyEditor *editor, gint pos) { gint orig_pos = pos; /* the position for the calltip */ gint lexer; gint style; gchar word[GEANY_MAX_WORD_LENGTH]; gchar *str; ScintillaObject *sci; g_return_val_if_fail(editor != NULL, FALSE); g_return_val_if_fail(editor->document->file_type != NULL, FALSE); sci = editor->sci; lexer = sci_get_lexer(sci); if (pos == -1) { /* position of '(' is unknown, so go backwards from current position to find it */ pos = sci_get_current_position(sci); pos--; orig_pos = pos; pos = (lexer == SCLEX_LATEX) ? find_previous_brace(sci, pos) : find_start_bracket(sci, pos); if (pos == -1) return FALSE; } /* the style 1 before the brace (which may be highlighted) */ style = sci_get_style_at(sci, pos - 1); if (! highlighting_is_code_style(lexer, style)) return FALSE; while (pos > 0 && isspace(sci_get_char_at(sci, pos - 1))) pos--; /* skip possible generic/template specification, like foo() */ if (sci_get_char_at(sci, pos - 1) == '>') { pos = sci_find_matching_brace(sci, pos - 1); if (pos == -1) return FALSE; while (pos > 0 && isspace(sci_get_char_at(sci, pos - 1))) pos--; } word[0] = '\0'; editor_find_current_word(editor, pos - 1, word, sizeof word, NULL); if (word[0] == '\0') return FALSE; str = find_calltip(word, editor->document->file_type); if (str) { g_free(calltip.text); /* free the old calltip */ calltip.text = str; calltip.pos = orig_pos; calltip.sci = sci; calltip.set = TRUE; utils_wrap_string(calltip.text, -1); SSM(sci, SCI_CALLTIPSHOW, orig_pos, (sptr_t) calltip.text); return TRUE; } return FALSE; } /* Current document & global tags autocompletion */ static gboolean autocomplete_tags(GeanyEditor *editor, GeanyFiletype *ft, const gchar *root, gsize rootlen) { GeanyDocument *doc = editor->document; const gchar *current_scope = NULL; guint current_line; GPtrArray *tags; gboolean found; g_return_val_if_fail(editor && doc, FALSE); symbols_get_current_function(doc, ¤t_scope); current_line = sci_get_current_line(editor->sci) + 1; tags = tm_workspace_find_prefix(root, doc->tm_file, current_line, current_scope, editor_prefs.autocompletion_max_entries); found = tags->len > 0; if (found) show_tags_list(editor, tags, rootlen); g_ptr_array_free(tags, TRUE); return found; } static gboolean autocomplete_check_html(GeanyEditor *editor, gint style, gint pos) { GeanyFiletype *ft = editor->document->file_type; gboolean try = FALSE; /* use entity completion when style is not JavaScript, ASP, Python, PHP, ... * (everything after SCE_HJ_START is for embedded scripting languages) */ if (ft->id == GEANY_FILETYPES_HTML && style < SCE_HJ_START) try = TRUE; else if (sci_get_lexer(editor->sci) == SCLEX_XML && style < SCE_HJ_START) try = TRUE; else if (ft->id == GEANY_FILETYPES_PHP) { /* use entity completion when style is outside of PHP styles */ if (! is_style_php(style)) try = TRUE; } if (try) { gchar root[GEANY_MAX_WORD_LENGTH]; gchar *tmp; read_current_word(editor, pos, root, sizeof(root), GEANY_WORDCHARS"&", TRUE); /* Allow something like ""some text"". * for entity completion we want to have completion for '&' within words. */ tmp = strchr(root, '&'); if (tmp != NULL) { return autocomplete_tags(editor, filetypes_index(GEANY_FILETYPES_HTML), tmp, strlen(tmp)); } } return FALSE; } /* Algorithm based on based on Scite's StartAutoCompleteWord() * @returns a sorted list of words matching @p root */ static GSList *get_doc_words(ScintillaObject *sci, gchar *root, gsize rootlen) { gchar *word; gint len, current, word_end; gint pos_find, flags; guint word_length; gsize nmatches = 0; GSList *words = NULL; struct Sci_TextToFind ttf; len = sci_get_length(sci); current = sci_get_current_position(sci) - rootlen; ttf.lpstrText = root; ttf.chrg.cpMin = 0; ttf.chrg.cpMax = len; ttf.chrgText.cpMin = 0; ttf.chrgText.cpMax = 0; flags = SCFIND_WORDSTART | SCFIND_MATCHCASE; /* search the whole document for the word root and collect results */ pos_find = SSM(sci, SCI_FINDTEXT, flags, (uptr_t) &ttf); while (pos_find >= 0 && pos_find < len) { word_end = pos_find + rootlen; if (pos_find != current) { word_end = sci_word_end_position(sci, word_end, TRUE); word_length = word_end - pos_find; if (word_length > rootlen) { word = sci_get_contents_range(sci, pos_find, word_end); /* search whether we already have the word in, otherwise add it */ if (g_slist_find_custom(words, word, (GCompareFunc)strcmp) != NULL) g_free(word); else { words = g_slist_prepend(words, word); nmatches++; } if (nmatches == editor_prefs.autocompletion_max_entries) break; } } ttf.chrg.cpMin = word_end; pos_find = SSM(sci, SCI_FINDTEXT, flags, (uptr_t) &ttf); } return g_slist_sort(words, (GCompareFunc)utils_str_casecmp); } static gboolean autocomplete_doc_word(GeanyEditor *editor, gchar *root, gsize rootlen) { ScintillaObject *sci = editor->sci; GSList *words, *node; GString *str; guint n_words = 0; words = get_doc_words(sci, root, rootlen); if (!words) { SSM(sci, SCI_AUTOCCANCEL, 0, 0); return FALSE; } str = g_string_sized_new(rootlen * 2 * 10); foreach_slist(node, words) { g_string_append(str, node->data); g_free(node->data); if (node->next) g_string_append_c(str, '\n'); n_words++; } if (n_words >= editor_prefs.autocompletion_max_entries) g_string_append(str, "\n..."); g_slist_free(words); show_autocomplete(sci, rootlen, str); g_string_free(str, TRUE); return TRUE; } gboolean editor_start_auto_complete(GeanyEditor *editor, gint pos, gboolean force) { gint rootlen, lexer, style; gchar *root; gchar cword[GEANY_MAX_WORD_LENGTH]; ScintillaObject *sci; gboolean ret = FALSE; const gchar *wordchars; GeanyFiletype *ft; g_return_val_if_fail(editor != NULL, FALSE); if (! editor_prefs.auto_complete_symbols && ! force) return FALSE; /* If we are at the beginning of the document, we skip autocompletion as we can't determine the * necessary styling information */ if (G_UNLIKELY(pos < 2)) return FALSE; sci = editor->sci; ft = editor->document->file_type; lexer = sci_get_lexer(sci); style = sci_get_style_at(sci, pos - 2); /* don't autocomplete in comments and strings */ if (!force && !highlighting_is_code_style(lexer, style)) return FALSE; ret = autocomplete_check_html(editor, style, pos); if (ft->id == GEANY_FILETYPES_LATEX) wordchars = GEANY_WORDCHARS"\\"; /* add \ to word chars if we are in a LaTeX file */ else if (ft->id == GEANY_FILETYPES_CSS) wordchars = GEANY_WORDCHARS"-"; /* add - because they are part of property names */ else wordchars = GEANY_WORDCHARS; read_current_word(editor, pos, cword, sizeof(cword), wordchars, TRUE); root = cword; rootlen = strlen(root); if (ret || force) { if (autocomplete_scope_shown) { autocomplete_scope_shown = FALSE; if (!ret) sci_send_command(sci, SCI_AUTOCCANCEL); } } else { ret = autocomplete_scope(editor, root, rootlen); if (!ret && autocomplete_scope_shown) sci_send_command(sci, SCI_AUTOCCANCEL); autocomplete_scope_shown = ret; } if (!ret && rootlen > 0) { if (ft->id == GEANY_FILETYPES_PHP && style == SCE_HPHP_DEFAULT && rootlen == 3 && strcmp(root, "php") == 0 && pos >= 5 && sci_get_char_at(sci, pos - 5) == '<' && sci_get_char_at(sci, pos - 4) == '?') { /* nothing, don't complete PHP open tags */ } else { /* force is set when called by keyboard shortcut, otherwise start at the * editor_prefs.symbolcompletion_min_chars'th char */ if (force || rootlen >= editor_prefs.symbolcompletion_min_chars) { /* complete tags, except if forcing when completion is already visible */ if (!(force && SSM(sci, SCI_AUTOCACTIVE, 0, 0))) ret = autocomplete_tags(editor, editor->document->file_type, root, rootlen); /* If forcing and there's nothing else to show, complete from words in document */ if (!ret && (force || editor_prefs.autocomplete_doc_words)) ret = autocomplete_doc_word(editor, root, rootlen); } } } if (!ret && force) utils_beep(); return ret; } static const gchar *snippets_find_completion_by_name(const gchar *type, const gchar *name) { gchar *result = NULL; GHashTable *tmp; g_return_val_if_fail(type != NULL && name != NULL, NULL); tmp = g_hash_table_lookup(snippet_hash, type); if (tmp != NULL) { result = g_hash_table_lookup(tmp, name); } /* whether nothing is set for the current filetype(tmp is NULL) or * the particular completion for this filetype is not set (result is NULL) */ if (tmp == NULL || result == NULL) { tmp = g_hash_table_lookup(snippet_hash, "Default"); if (tmp != NULL) { result = g_hash_table_lookup(tmp, name); } } /* if result is still NULL here, no completion could be found */ /* result is owned by the hash table and will be freed when the table will destroyed */ return result; } static void snippets_replace_specials(gpointer key, gpointer value, gpointer user_data) { gchar *needle; GString *pattern = user_data; g_return_if_fail(key != NULL); g_return_if_fail(value != NULL); needle = g_strconcat("%", (gchar*) key, "%", NULL); utils_string_replace_all(pattern, needle, (gchar*) value); g_free(needle); } static void fix_indentation(GeanyEditor *editor, GString *buf) { const GeanyIndentPrefs *iprefs = editor_get_indent_prefs(editor); gchar *whitespace; GRegex *regex; gint cflags = G_REGEX_MULTILINE; /* transform leading tabs into indent widths (in spaces) */ whitespace = g_strnfill(iprefs->width, ' '); regex = g_regex_new("^ *(\t)", cflags, 0, NULL); while (utils_string_regex_replace_all(buf, regex, 1, whitespace, TRUE)); g_regex_unref(regex); /* remaining tabs are for alignment */ if (iprefs->type != GEANY_INDENT_TYPE_TABS) utils_string_replace_all(buf, "\t", whitespace); /* use leading tabs */ if (iprefs->type != GEANY_INDENT_TYPE_SPACES) { gchar *str; /* for tabs+spaces mode we want the real tab width, not indent width */ SETPTR(whitespace, g_strnfill(sci_get_tab_width(editor->sci), ' ')); str = g_strdup_printf("^\t*(%s)", whitespace); regex = g_regex_new(str, cflags, 0, NULL); while (utils_string_regex_replace_all(buf, regex, 1, "\t", TRUE)); g_regex_unref(regex); g_free(str); } g_free(whitespace); } typedef struct { Sci_Position start, len; } SelectionRange; #define CURSOR_PLACEHOLDER "_" /* Would rather use … but not all docs are unicode */ /* Replaces the internal cursor markers with the placeholder suitable for * display. Except for the first cursor if indicator_for_first is FALSE, * which is simply deleted. * * Returns insertion points as SelectionRange list, so that the caller * can use the positions (currently for indicators). */ static GSList *replace_cursor_markers(GeanyEditor *editor, GString *template, gboolean indicator_for_first) { gint i = 0; GSList *temp_list = NULL; gint cursor_steps = 0; SelectionRange *sel; while (TRUE) { cursor_steps = utils_string_find(template, cursor_steps, -1, geany_cursor_marker); if (cursor_steps == -1) break; sel = g_new0(SelectionRange, 1); sel->start = cursor_steps; g_string_erase(template, cursor_steps, strlen(geany_cursor_marker)); if (i > 0 || indicator_for_first) { g_string_insert(template, cursor_steps, CURSOR_PLACEHOLDER); sel->len = sizeof(CURSOR_PLACEHOLDER) - 1; } i += 1; temp_list = g_slist_append(temp_list, sel); } return temp_list; } /** Inserts text, replacing \\t tab chars (@c 0x9) and \\n newline chars (@c 0xA) * accordingly for the document. * - Leading tabs are replaced with the correct indentation. * - Non-leading tabs are replaced with spaces (except when using 'Tabs' indent type). * - Newline chars are replaced with the correct line ending string. * This is very useful for inserting code without having to handle the indent * type yourself (Tabs & Spaces mode can be tricky). * @param editor Editor. * @param text Intended as e.g. @c "if (foo)\n\tbar();". * @param insert_pos Document position to insert text at. * @param cursor_index If >= 0, the index into @a text to place the cursor. * @param newline_indent_size Indentation size (in spaces) to insert for each newline; use * -1 to read the indent size from the line with @a insert_pos on it. * @param replace_newlines Whether to replace newlines. If * newlines have been replaced already, this should be false, to avoid errors e.g. on Windows. * @warning Make sure all \\t tab chars in @a text are intended as indent widths or alignment, * not hard tabs, as those won't be preserved. * @note This doesn't scroll the cursor in view afterwards. **/ GEANY_API_SYMBOL void editor_insert_text_block(GeanyEditor *editor, const gchar *text, gint insert_pos, gint cursor_index, gint newline_indent_size, gboolean replace_newlines) { ScintillaObject *sci = editor->sci; gint line_start = sci_get_line_from_position(sci, insert_pos); GString *buf; const gchar *eol = editor_get_eol_char(editor); GSList *jump_locs, *item; g_return_if_fail(text); g_return_if_fail(editor != NULL); g_return_if_fail(insert_pos >= 0); buf = g_string_new(text); if (cursor_index >= 0) g_string_insert(buf, cursor_index, geany_cursor_marker); /* remember cursor pos */ if (newline_indent_size == -1) { /* count indent size up to insert_pos instead of asking sci * because there may be spaces after it */ gchar *tmp = sci_get_line(sci, line_start); gint idx; idx = insert_pos - sci_get_position_from_line(sci, line_start); tmp[idx] = '\0'; newline_indent_size = count_indent_size(editor, tmp); g_free(tmp); } /* Add line indents (in spaces) */ if (newline_indent_size > 0) { const gchar *nl = replace_newlines ? "\n" : eol; gchar *whitespace; whitespace = g_strnfill(newline_indent_size, ' '); SETPTR(whitespace, g_strconcat(nl, whitespace, NULL)); utils_string_replace_all(buf, nl, whitespace); g_free(whitespace); } /* transform line endings */ if (replace_newlines) utils_string_replace_all(buf, "\n", eol); fix_indentation(editor, buf); jump_locs = replace_cursor_markers(editor, buf, cursor_index < 0); sci_insert_text(sci, insert_pos, buf->str); foreach_list(item, jump_locs) { SelectionRange *sel = item->data; gint start = insert_pos + sel->start; gint end = start + sel->len; editor_indicator_set_on_range(editor, GEANY_INDICATOR_SNIPPET, start, end); /* jump to first cursor position initially */ if (item == jump_locs) sci_set_selection(sci, start, end); } /* Set cursor to the requested index, or by default to after the snippet */ if (cursor_index >= 0) sci_set_current_position(sci, insert_pos + cursor_index, FALSE); else if (jump_locs == NULL) sci_set_current_position(sci, insert_pos + buf->len, FALSE); g_slist_free_full(jump_locs, g_free); g_string_free(buf, TRUE); } static gboolean find_next_snippet_indicator(GeanyEditor *editor, SelectionRange *sel) { ScintillaObject *sci = editor->sci; gint pos = sci_get_current_position(sci); if (pos == sci_get_length(sci)) return FALSE; /* EOF */ /* Rewind the cursor a bit if we're in the middle (or start) of an indicator, * and treat that as the next indicator. */ while (SSM(sci, SCI_INDICATORVALUEAT, GEANY_INDICATOR_SNIPPET, pos) && pos > 0) pos -= 1; /* Be careful at the beginning of the file */ if (SSM(sci, SCI_INDICATORVALUEAT, GEANY_INDICATOR_SNIPPET, pos)) sel->start = pos; else sel->start = SSM(sci, SCI_INDICATOREND, GEANY_INDICATOR_SNIPPET, pos); sel->len = SSM(sci, SCI_INDICATOREND, GEANY_INDICATOR_SNIPPET, sel->start) - sel->start; /* 0 if there is no remaining cursor */ return sel->len > 0; } /* Move the cursor to the next specified cursor position in an inserted snippet. * Can, and should, be optimized to give better results */ gboolean editor_goto_next_snippet_cursor(GeanyEditor *editor) { ScintillaObject *sci = editor->sci; SelectionRange sel; if (find_next_snippet_indicator(editor, &sel)) { sci_indicator_set(sci, GEANY_INDICATOR_SNIPPET); sci_set_selection(sci, sel.start, sel.start + sel.len); return TRUE; } else { return FALSE; } } static void snippets_make_replacements(GeanyEditor *editor, GString *pattern) { GHashTable *specials; /* replace 'special' completions */ specials = g_hash_table_lookup(snippet_hash, "Special"); if (G_LIKELY(specials != NULL)) { g_hash_table_foreach(specials, snippets_replace_specials, pattern); } /* now transform other wildcards */ utils_string_replace_all(pattern, "%newline%", "\n"); utils_string_replace_all(pattern, "%ws%", "\t"); /* replace %cursor% by a very unlikely string marker */ utils_string_replace_all(pattern, "%cursor%", geany_cursor_marker); /* unescape '%' after all %wildcards% */ templates_replace_valist(pattern, "{pc}", "%", NULL); /* replace any template {foo} wildcards */ templates_replace_common(pattern, editor->document->file_name, editor->document->file_type, NULL); } static gboolean snippets_complete_constructs(GeanyEditor *editor, gint pos, const gchar *word) { ScintillaObject *sci = editor->sci; gchar *str; const gchar *completion; gint str_len; gint ft_id = editor->document->file_type->id; str = g_strdup(word); g_strstrip(str); completion = snippets_find_completion_by_name(filetypes[ft_id]->name, str); if (completion == NULL) { g_free(str); return FALSE; } /* remove the typed word, it will be added again by the used auto completion * (not really necessary but this makes the auto completion more flexible, * e.g. with a completion like hi=hello, so typing "hi" will result in "hello") */ str_len = strlen(str); sci_set_selection_start(sci, pos - str_len); sci_set_selection_end(sci, pos); sci_replace_sel(sci, ""); pos -= str_len; /* pos has changed while deleting */ editor_insert_snippet(editor, pos, completion); sci_scroll_caret(sci); g_free(str); return TRUE; } static gboolean at_eol(ScintillaObject *sci, gint pos) { gint line = sci_get_line_from_position(sci, pos); gchar c; /* skip any trailing spaces */ while (TRUE) { c = sci_get_char_at(sci, pos); if (c == ' ' || c == '\t') pos++; else break; } return (pos == sci_get_line_end_position(sci, line)); } gboolean editor_complete_snippet(GeanyEditor *editor, gint pos) { gboolean result = FALSE; const gchar *wc; const gchar *word; ScintillaObject *sci; g_return_val_if_fail(editor != NULL, FALSE); sci = editor->sci; if (sci_has_selection(sci)) return FALSE; /* return if we are editing an existing line (chars on right of cursor) */ if (keybindings_lookup_item(GEANY_KEY_GROUP_EDITOR, GEANY_KEYS_EDITOR_COMPLETESNIPPET)->key == GDK_KEY_space && ! editor_prefs.complete_snippets_whilst_editing && ! at_eol(sci, pos)) return FALSE; wc = snippets_find_completion_by_name("Special", "wordchars"); word = editor_read_word_stem(editor, pos, wc); /* prevent completion of "for " */ if (!EMPTY(word) && ! isspace(sci_get_char_at(sci, pos - 1))) /* pos points to the line end char so use pos -1 */ { sci_start_undo_action(sci); /* needed because we insert a space separately from construct */ result = snippets_complete_constructs(editor, pos, word); sci_end_undo_action(sci); if (result) sci_cancel(sci); /* cancel any autocompletion list, etc */ } return result; } static void insert_closing_tag(GeanyEditor *editor, gint pos, gchar ch, const gchar *tag_name) { ScintillaObject *sci = editor->sci; gchar *to_insert = NULL; if (ch == '/') { const gchar *gt = ">"; /* if there is already a '>' behind the cursor, don't add it */ if (sci_get_char_at(sci, pos) == '>') gt = ""; to_insert = g_strconcat(tag_name, gt, NULL); } else to_insert = g_strconcat("", NULL); sci_start_undo_action(sci); sci_replace_sel(sci, to_insert); if (ch == '>') sci_set_selection(sci, pos, pos); sci_end_undo_action(sci); g_free(to_insert); } /* * (stolen from anjuta and heavily modified) * This routine will auto complete XML or HTML tags that are still open by closing them * @param ch The character we are dealing with, currently only works with the '>' character * @return True if handled, false otherwise */ static gboolean handle_xml(GeanyEditor *editor, gint pos, gchar ch) { ScintillaObject *sci = editor->sci; gint lexer = sci_get_lexer(sci); gint min, size, style; gchar *str_found, sel[512]; gboolean result = FALSE; /* If the user has turned us off, quit now. * This may make sense only in certain languages */ if (! editor_prefs.auto_close_xml_tags || (lexer != SCLEX_HTML && lexer != SCLEX_XML)) return FALSE; /* return if we are inside any embedded script */ style = sci_get_style_at(sci, pos); if (style > SCE_H_XCCOMMENT && ! highlighting_is_string_style(lexer, style)) return FALSE; /* if ch is /, check for */ sci_get_text_range(sci, min, pos, sel); sel[sizeof(sel) - 1] = '\0'; if (ch == '>' && sel[pos - min - 2] == '/') /* User typed something like "
" */ return FALSE; size = pos - min; if (ch == '/') size -= 2; /* skip sci); gsize count = 0; g_return_val_if_fail(base_indent, 0); for (ptr = base_indent; *ptr != 0; ptr++) { switch (*ptr) { case ' ': count++; break; case '\t': count += tab_size; break; default: return count; } } return count; } /* Handles special cases where HTML is embedded in another language or * another language is embedded in HTML */ static GeanyFiletype *editor_get_filetype_at_line(GeanyEditor *editor, gint line) { gint style, line_start; GeanyFiletype *current_ft; g_return_val_if_fail(editor != NULL, NULL); g_return_val_if_fail(editor->document->file_type != NULL, NULL); current_ft = editor->document->file_type; line_start = sci_get_position_from_line(editor->sci, line); style = sci_get_style_at(editor->sci, line_start); /* Handle PHP filetype with embedded HTML */ if (current_ft->id == GEANY_FILETYPES_PHP && ! is_style_php(style)) current_ft = filetypes[GEANY_FILETYPES_HTML]; /* Handle languages embedded in HTML */ if (current_ft->id == GEANY_FILETYPES_HTML) { /* Embedded JS */ if (style >= SCE_HJ_DEFAULT && style <= SCE_HJ_REGEX) current_ft = filetypes[GEANY_FILETYPES_JS]; /* ASP JS */ else if (style >= SCE_HJA_DEFAULT && style <= SCE_HJA_REGEX) current_ft = filetypes[GEANY_FILETYPES_JS]; /* Embedded VB */ else if (style >= SCE_HB_DEFAULT && style <= SCE_HB_STRINGEOL) current_ft = filetypes[GEANY_FILETYPES_BASIC]; /* ASP VB */ else if (style >= SCE_HBA_DEFAULT && style <= SCE_HBA_STRINGEOL) current_ft = filetypes[GEANY_FILETYPES_BASIC]; /* Embedded Python */ else if (style >= SCE_HP_DEFAULT && style <= SCE_HP_IDENTIFIER) current_ft = filetypes[GEANY_FILETYPES_PYTHON]; /* ASP Python */ else if (style >= SCE_HPA_DEFAULT && style <= SCE_HPA_IDENTIFIER) current_ft = filetypes[GEANY_FILETYPES_PYTHON]; /* Embedded PHP */ else if ((style >= SCE_HPHP_DEFAULT && style <= SCE_HPHP_OPERATOR) || style == SCE_HPHP_COMPLEX_VARIABLE) { current_ft = filetypes[GEANY_FILETYPES_PHP]; } } /* Ensure the filetype's config is loaded */ filetypes_load_config(current_ft->id, FALSE); return current_ft; } static void real_comment_multiline(GeanyEditor *editor, gint line_start, gint last_line) { const gchar *eol; gchar *str_begin, *str_end; const gchar *co, *cc; gint line_len; GeanyFiletype *ft; g_return_if_fail(editor != NULL && editor->document->file_type != NULL); ft = editor_get_filetype_at_line(editor, line_start); eol = editor_get_eol_char(editor); if (! filetype_get_comment_open_close(ft, FALSE, &co, &cc)) g_return_if_reached(); str_begin = g_strdup_printf("%s%s", (co != NULL) ? co : "", eol); str_end = g_strdup_printf("%s%s", (cc != NULL) ? cc : "", eol); /* insert the comment strings */ sci_insert_text(editor->sci, line_start, str_begin); line_len = sci_get_position_from_line(editor->sci, last_line + 2); sci_insert_text(editor->sci, line_len, str_end); g_free(str_begin); g_free(str_end); } /* find @p text inside the range of the current style */ static gint find_in_current_style(ScintillaObject *sci, const gchar *text, gboolean backwards) { gint start = sci_get_current_position(sci); gint end = start; gint len = sci_get_length(sci); gint current_style = sci_get_style_at(sci, start); struct Sci_TextToFind ttf; while (start > 0 && sci_get_style_at(sci, start - 1) == current_style) start -= 1; while (end < len && sci_get_style_at(sci, end + 1) == current_style) end += 1; ttf.lpstrText = (gchar*) text; ttf.chrg.cpMin = backwards ? end + 1 : start; ttf.chrg.cpMax = backwards ? start : end + 1; return sci_find_text(sci, 0, &ttf); } static void sci_delete_line(ScintillaObject *sci, gint line) { gint start = sci_get_position_from_line(sci, line); gint len = sci_get_line_length(sci, line); SSM(sci, SCI_DELETERANGE, start, len); } static gboolean real_uncomment_multiline(GeanyEditor *editor) { /* find the beginning of the multi line comment */ gint start, end, start_line, end_line; GeanyFiletype *ft; const gchar *co, *cc; g_return_val_if_fail(editor != NULL && editor->document->file_type != NULL, FALSE); ft = editor_get_filetype_at_line(editor, sci_get_current_line(editor->sci)); if (! filetype_get_comment_open_close(ft, FALSE, &co, &cc)) g_return_val_if_reached(FALSE); start = find_in_current_style(editor->sci, co, TRUE); end = find_in_current_style(editor->sci, cc, FALSE); if (start < 0 || end < 0 || start > end /* who knows */) return FALSE; start_line = sci_get_line_from_position(editor->sci, start); end_line = sci_get_line_from_position(editor->sci, end); /* remove comment close chars */ SSM(editor->sci, SCI_DELETERANGE, end, strlen(cc)); if (sci_is_blank_line(editor->sci, end_line)) sci_delete_line(editor->sci, end_line); /* remove comment open chars (do it last since it would move the end position) */ SSM(editor->sci, SCI_DELETERANGE, start, strlen(co)); if (sci_is_blank_line(editor->sci, start_line)) sci_delete_line(editor->sci, start_line); return TRUE; } static gint get_multiline_comment_style(GeanyEditor *editor, gint line_start) { gint lexer = sci_get_lexer(editor->sci); gint style_comment; /* List only those lexers which support multi line comments */ switch (lexer) { case SCLEX_XML: case SCLEX_HTML: case SCLEX_PHPSCRIPT: { if (is_style_php(sci_get_style_at(editor->sci, line_start))) style_comment = SCE_HPHP_COMMENT; else style_comment = SCE_H_COMMENT; break; } case SCLEX_HASKELL: case SCLEX_LITERATEHASKELL: style_comment = SCE_HA_COMMENTBLOCK; break; case SCLEX_LUA: style_comment = SCE_LUA_COMMENT; break; case SCLEX_CSS: style_comment = SCE_CSS_COMMENT; break; case SCLEX_SQL: style_comment = SCE_SQL_COMMENT; break; case SCLEX_CAML: style_comment = SCE_CAML_COMMENT; break; case SCLEX_D: style_comment = SCE_D_COMMENT; break; case SCLEX_PASCAL: style_comment = SCE_PAS_COMMENT; break; case SCLEX_RUST: style_comment = SCE_RUST_COMMENTBLOCK; break; default: style_comment = SCE_C_COMMENT; } return style_comment; } /* set toggle to TRUE if the caller is the toggle function, FALSE otherwise * returns the amount of uncommented single comment lines, in case of multi line uncomment * it returns just 1 */ gint editor_do_uncomment(GeanyEditor *editor, gint line, gboolean toggle) { gint first_line, last_line; gint x, i, line_start, line_len; gint sel_start, sel_end; gint count = 0; gsize co_len; gchar sel[256]; const gchar *co, *cc; gboolean single_line = FALSE; GeanyFiletype *ft; g_return_val_if_fail(editor != NULL && editor->document->file_type != NULL, 0); if (line < 0) { /* use selection or current line */ sel_start = sci_get_selection_start(editor->sci); sel_end = sci_get_selection_end(editor->sci); first_line = sci_get_line_from_position(editor->sci, sel_start); /* Find the last line with chars selected (not EOL char) */ last_line = sci_get_line_from_position(editor->sci, sel_end - editor_get_eol_char_len(editor)); last_line = MAX(first_line, last_line); } else { first_line = last_line = line; sel_start = sel_end = sci_get_position_from_line(editor->sci, line); } ft = editor_get_filetype_at_line(editor, first_line); if (! filetype_get_comment_open_close(ft, TRUE, &co, &cc)) return 0; co_len = strlen(co); if (co_len == 0) return 0; sci_start_undo_action(editor->sci); for (i = first_line; i <= last_line; i++) { gint buf_len; line_start = sci_get_position_from_line(editor->sci, i); line_len = sci_get_line_end_position(editor->sci, i) - line_start; x = 0; buf_len = MIN((gint)sizeof(sel) - 1, line_len); if (buf_len <= 0) continue; sci_get_text_range(editor->sci, line_start, line_start + buf_len, sel); sel[buf_len] = '\0'; while (isspace(sel[x])) x++; /* to skip blank lines */ if (x < line_len && sel[x] != '\0') { /* use single line comment */ if (EMPTY(cc)) { single_line = TRUE; if (toggle) { gsize tm_len = strlen(editor_prefs.comment_toggle_mark); if (strncmp(sel + x, co, co_len) != 0 || strncmp(sel + x + co_len, editor_prefs.comment_toggle_mark, tm_len) != 0) continue; co_len += tm_len; } else { if (strncmp(sel + x, co, co_len) != 0) continue; } sci_set_selection(editor->sci, line_start + x, line_start + x + co_len); sci_replace_sel(editor->sci, ""); count++; } /* use multi line comment */ else { gint style_comment; /* skip lines which are already comments */ style_comment = get_multiline_comment_style(editor, line_start); if (sci_get_style_at(editor->sci, line_start + x) == style_comment) { if (real_uncomment_multiline(editor)) count = 1; } /* break because we are already on the last line */ break; } } } sci_end_undo_action(editor->sci); /* restore selection if there is one * but don't touch the selection if caller is editor_do_comment_toggle */ if (! toggle && sel_start < sel_end) { if (single_line) { sci_set_selection_start(editor->sci, sel_start - co_len); sci_set_selection_end(editor->sci, sel_end - (count * co_len)); } else { gint eol_len = editor_get_eol_char_len(editor); sci_set_selection_start(editor->sci, sel_start - co_len - eol_len); sci_set_selection_end(editor->sci, sel_end - co_len - eol_len); } } return count; } void editor_do_comment_toggle(GeanyEditor *editor) { gint first_line, last_line; gint x, i, line_start, line_len, first_line_start, last_line_start; gint sel_start, sel_end; gint count_commented = 0, count_uncommented = 0; gchar sel[256]; const gchar *co, *cc; gboolean single_line = FALSE; gboolean first_line_was_comment = FALSE; gboolean last_line_was_comment = FALSE; gsize co_len; gsize tm_len = strlen(editor_prefs.comment_toggle_mark); GeanyFiletype *ft; g_return_if_fail(editor != NULL && editor->document->file_type != NULL); sel_start = sci_get_selection_start(editor->sci); sel_end = sci_get_selection_end(editor->sci); first_line = sci_get_line_from_position(editor->sci, sel_start); /* Find the last line with chars selected (not EOL char) */ last_line = sci_get_line_from_position(editor->sci, sel_end - editor_get_eol_char_len(editor)); last_line = MAX(first_line, last_line); first_line_start = sci_get_position_from_line(editor->sci, first_line); last_line_start = sci_get_position_from_line(editor->sci, last_line); ft = editor_get_filetype_at_line(editor, first_line); if (! filetype_get_comment_open_close(ft, TRUE, &co, &cc)) return; co_len = strlen(co); if (co_len == 0) return; sci_start_undo_action(editor->sci); for (i = first_line; i <= last_line; i++) { gint buf_len; line_start = sci_get_position_from_line(editor->sci, i); line_len = sci_get_line_end_position(editor->sci, i) - line_start; x = 0; buf_len = MIN((gint)sizeof(sel) - 1, line_len); if (buf_len < 0) continue; sci_get_text_range(editor->sci, line_start, line_start + buf_len, sel); sel[buf_len] = '\0'; while (isspace(sel[x])) x++; /* use single line comment */ if (EMPTY(cc)) { gboolean do_continue = FALSE; single_line = TRUE; if (strncmp(sel + x, co, co_len) == 0 && strncmp(sel + x + co_len, editor_prefs.comment_toggle_mark, tm_len) == 0) { do_continue = TRUE; } if (do_continue && i == first_line) first_line_was_comment = TRUE; last_line_was_comment = do_continue; if (do_continue) { count_uncommented += editor_do_uncomment(editor, i, TRUE); continue; } /* we are still here, so the above lines were not already comments, so comment it */ count_commented += editor_do_comment(editor, i, FALSE, TRUE, TRUE); } /* use multi line comment */ else { gint style_comment; /* skip lines which are already comments */ style_comment = get_multiline_comment_style(editor, line_start); if (sci_get_style_at(editor->sci, line_start + x) == style_comment) { if (real_uncomment_multiline(editor)) count_uncommented++; } else { real_comment_multiline(editor, line_start, last_line); count_commented++; } /* break because we are already on the last line */ break; } } sci_end_undo_action(editor->sci); co_len += tm_len; /* restore selection or caret position */ if (single_line) { gint a = (first_line_was_comment) ? - (gint) co_len : (gint) co_len; gint indent_len; /* don't modify sel_start when the selection starts within indentation */ read_indent(editor, sel_start); indent_len = (gint) strlen(indent); if ((sel_start - first_line_start) <= indent_len) a = 0; /* if the selection start was inside the comment mark, adjust the position */ else if (first_line_was_comment && sel_start >= (first_line_start + indent_len) && sel_start <= (first_line_start + indent_len + (gint) co_len)) { a = (first_line_start + indent_len) - sel_start; } if (sel_start < sel_end) { gint b = (count_commented * (gint) co_len) - (count_uncommented * (gint) co_len); /* same for selection end, but here we add an offset on the offset above */ read_indent(editor, sel_end + b); indent_len = (gint) strlen(indent); if ((sel_end - last_line_start) < indent_len) b += last_line_was_comment ? (gint) co_len : -(gint) co_len; else if (last_line_was_comment && sel_end >= (last_line_start + indent_len) && sel_end <= (last_line_start + indent_len + (gint) co_len)) { b += (gint) co_len - (sel_end - (last_line_start + indent_len)); } sci_set_selection_start(editor->sci, sel_start + a); sci_set_selection_end(editor->sci, sel_end + b); } else sci_set_current_position(editor->sci, sel_start + a, TRUE); } else { gint eol_len = editor_get_eol_char_len(editor); if (count_uncommented > 0) { sci_set_selection_start(editor->sci, sel_start - (gint) co_len + eol_len); sci_set_selection_end(editor->sci, sel_end - (gint) co_len + eol_len); } else if (count_commented > 0) { sci_set_selection_start(editor->sci, sel_start + (gint) co_len - eol_len); sci_set_selection_end(editor->sci, sel_end + (gint) co_len - eol_len); } if (sel_start >= sel_end) sci_scroll_caret(editor->sci); } } /* set toggle to TRUE if the caller is the toggle function, FALSE otherwise */ gint editor_do_comment(GeanyEditor *editor, gint line, gboolean allow_empty_lines, gboolean toggle, gboolean single_comment) { gint first_line, last_line; gint x, i, line_start, line_len; gint sel_start, sel_end, co_len; gint count = 0; gchar sel[256]; const gchar *co, *cc; gboolean single_line = FALSE; GeanyFiletype *ft; g_return_val_if_fail(editor != NULL && editor->document->file_type != NULL, 0); if (line < 0) { /* use selection or current line */ sel_start = sci_get_selection_start(editor->sci); sel_end = sci_get_selection_end(editor->sci); first_line = sci_get_line_from_position(editor->sci, sel_start); /* Find the last line with chars selected (not EOL char) */ last_line = sci_get_line_from_position(editor->sci, sel_end - editor_get_eol_char_len(editor)); last_line = MAX(first_line, last_line); } else { first_line = last_line = line; sel_start = sel_end = sci_get_position_from_line(editor->sci, line); } ft = editor_get_filetype_at_line(editor, first_line); if (! filetype_get_comment_open_close(ft, single_comment, &co, &cc)) return 0; co_len = strlen(co); if (co_len == 0) return 0; sci_start_undo_action(editor->sci); for (i = first_line; i <= last_line; i++) { gint buf_len; line_start = sci_get_position_from_line(editor->sci, i); line_len = sci_get_line_end_position(editor->sci, i) - line_start; x = 0; buf_len = MIN((gint)sizeof(sel) - 1, line_len); if (buf_len < 0) continue; sci_get_text_range(editor->sci, line_start, line_start + buf_len, sel); sel[buf_len] = '\0'; while (isspace(sel[x])) x++; /* to skip blank lines */ if (allow_empty_lines || (x < line_len && sel[x] != '\0')) { /* use single line comment */ if (EMPTY(cc)) { gint start = line_start; single_line = TRUE; if (ft->comment_use_indent) start = line_start + x; if (toggle) { gchar *text = g_strconcat(co, editor_prefs.comment_toggle_mark, NULL); sci_insert_text(editor->sci, start, text); g_free(text); } else sci_insert_text(editor->sci, start, co); count++; } /* use multi line comment */ else { gint style_comment; /* skip lines which are already comments */ style_comment = get_multiline_comment_style(editor, line_start); if (sci_get_style_at(editor->sci, line_start + x) == style_comment) continue; real_comment_multiline(editor, line_start, last_line); count = 1; /* break because we are already on the last line */ break; } } } sci_end_undo_action(editor->sci); /* restore selection if there is one * but don't touch the selection if caller is editor_do_comment_toggle */ if (! toggle && sel_start < sel_end) { if (single_line) { sci_set_selection_start(editor->sci, sel_start + co_len); sci_set_selection_end(editor->sci, sel_end + (count * co_len)); } else { gint eol_len = editor_get_eol_char_len(editor); sci_set_selection_start(editor->sci, sel_start + co_len + eol_len); sci_set_selection_end(editor->sci, sel_end + co_len + eol_len); } } return count; } static gboolean brace_timeout_active = FALSE; static gboolean delay_match_brace(G_GNUC_UNUSED gpointer user_data) { GeanyDocument *doc = document_get_current(); GeanyEditor *editor; gint brace_pos = GPOINTER_TO_INT(user_data); gint end_pos, cur_pos; brace_timeout_active = FALSE; if (!doc) return FALSE; editor = doc->editor; cur_pos = sci_get_current_position(editor->sci) - 1; if (cur_pos != brace_pos) { cur_pos++; if (cur_pos != brace_pos) { /* we have moved past the original brace_pos, but after the timeout * we may now be on a new brace, so check again */ editor_highlight_braces(editor, cur_pos); return FALSE; } } if (!utils_isbrace(sci_get_char_at(editor->sci, brace_pos), editor_prefs.brace_match_ltgt)) { editor_highlight_braces(editor, cur_pos); return FALSE; } end_pos = sci_find_matching_brace(editor->sci, brace_pos); if (end_pos >= 0) { gint col = MIN(sci_get_col_from_position(editor->sci, brace_pos), sci_get_col_from_position(editor->sci, end_pos)); SSM(editor->sci, SCI_SETHIGHLIGHTGUIDE, col, 0); SSM(editor->sci, SCI_BRACEHIGHLIGHT, brace_pos, end_pos); } else { SSM(editor->sci, SCI_SETHIGHLIGHTGUIDE, 0, 0); SSM(editor->sci, SCI_BRACEBADLIGHT, brace_pos, 0); } return FALSE; } static void editor_highlight_braces(GeanyEditor *editor, gint cur_pos) { gint brace_pos = cur_pos - 1; SSM(editor->sci, SCI_SETHIGHLIGHTGUIDE, 0, 0); SSM(editor->sci, SCI_BRACEBADLIGHT, (uptr_t)-1, 0); if (! utils_isbrace(sci_get_char_at(editor->sci, brace_pos), editor_prefs.brace_match_ltgt)) { brace_pos++; if (! utils_isbrace(sci_get_char_at(editor->sci, brace_pos), editor_prefs.brace_match_ltgt)) { return; } } if (!brace_timeout_active) { brace_timeout_active = TRUE; /* delaying matching makes scrolling faster e.g. holding down arrow keys */ g_timeout_add(100, delay_match_brace, GINT_TO_POINTER(brace_pos)); } } static gboolean in_block_comment(gint lexer, gint style) { switch (lexer) { case SCLEX_COBOL: case SCLEX_CPP: return (style == SCE_C_COMMENT || style == SCE_C_COMMENTDOC); case SCLEX_PASCAL: return (style == SCE_PAS_COMMENT || style == SCE_PAS_COMMENT2); case SCLEX_D: return (style == SCE_D_COMMENT || style == SCE_D_COMMENTDOC || style == SCE_D_COMMENTNESTED); case SCLEX_HTML: case SCLEX_PHPSCRIPT: return (style == SCE_HPHP_COMMENT); case SCLEX_CSS: return (style == SCE_CSS_COMMENT); case SCLEX_RUST: return (style == SCE_RUST_COMMENTBLOCK || style == SCE_RUST_COMMENTBLOCKDOC); default: return FALSE; } } static gboolean is_comment_char(gchar c, gint lexer) { if ((c == '*' || c == '+') && lexer == SCLEX_D) return TRUE; else if (c == '*') return TRUE; return FALSE; } static void auto_multiline(GeanyEditor *editor, gint cur_line) { ScintillaObject *sci = editor->sci; gint indent_pos, style; gint lexer = sci_get_lexer(sci); /* Use the start of the line enter was pressed on, to avoid any doc keyword styles */ indent_pos = sci_get_line_indent_position(sci, cur_line - 1); style = sci_get_style_at(sci, indent_pos); if (!in_block_comment(lexer, style)) return; /* Check whether the comment block continues on this line */ indent_pos = sci_get_line_indent_position(sci, cur_line); if (sci_get_style_at(sci, indent_pos) == style || indent_pos >= sci_get_length(sci)) { gchar *previous_line = sci_get_line(sci, cur_line - 1); /* the type of comment, '*' (C/C++/Java), '+' D comment that nests */ const gchar *continuation = (style == SCE_D_COMMENTNESTED) ? "+" : "*"; const gchar *whitespace = ""; /* to hold whitespace if needed */ gchar *result; gint len = strlen(previous_line); gint i; /* find and stop at end of multi line comment */ i = len - 1; while (i >= 0 && isspace(previous_line[i])) i--; if (i >= 1 && is_comment_char(previous_line[i - 1], lexer) && previous_line[i] == '/') { gint indent_len, indent_width; indent_pos = sci_get_line_indent_position(sci, cur_line); indent_len = sci_get_col_from_position(sci, indent_pos); indent_width = editor_get_indent_prefs(editor)->width; /* if there is one too many spaces, delete the last space, * to return to the indent used before the multiline comment was started. */ if (indent_len % indent_width == 1) SSM(sci, SCI_DELETEBACKNOTLINE, 0, 0); /* remove whitespace indent */ g_free(previous_line); return; } /* check whether we are on the second line of multi line comment */ i = 0; while (i < len && isspace(previous_line[i])) i++; /* get to start of the line */ if (i + 1 < len && previous_line[i] == '/' && is_comment_char(previous_line[i + 1], lexer)) { /* we are on the second line of a multi line comment, so we have to insert white space */ whitespace = " "; } else if (!(g_str_has_prefix(previous_line + i, continuation) && (i + 1 == len || isspace(previous_line[i + 1])))) { // previous line isn't formatted so abort g_free(previous_line); return; } result = g_strconcat(whitespace, continuation, " ", NULL); sci_add_text(sci, result); g_free(result); g_free(previous_line); } } #if 0 static gboolean editor_lexer_is_c_like(gint lexer) { switch (lexer) { case SCLEX_CPP: case SCLEX_D: return TRUE; default: return FALSE; } } #endif /* inserts a three-line comment at one line above current cursor position */ void editor_insert_multiline_comment(GeanyEditor *editor) { gchar *text; gint text_len; gint line; gint pos; gboolean have_multiline_comment = FALSE; GeanyDocument *doc; const gchar *co, *cc; g_return_if_fail(editor != NULL && editor->document->file_type != NULL); if (! filetype_get_comment_open_close(editor->document->file_type, FALSE, &co, &cc)) g_return_if_reached(); if (!EMPTY(cc)) have_multiline_comment = TRUE; sci_start_undo_action(editor->sci); doc = editor->document; /* insert three lines one line above of the current position */ line = sci_get_line_from_position(editor->sci, editor_info.click_pos); pos = sci_get_position_from_line(editor->sci, line); /* use the indent on the current line but only when comment indentation is used * and we don't have multi line comment characters */ if (editor->auto_indent && ! have_multiline_comment && doc->file_type->comment_use_indent) { read_indent(editor, editor_info.click_pos); text = g_strdup_printf("%s\n%s\n%s\n", indent, indent, indent); text_len = strlen(text); } else { text = g_strdup("\n\n\n"); text_len = 3; } sci_insert_text(editor->sci, pos, text); g_free(text); /* select the inserted lines for commenting */ sci_set_selection_start(editor->sci, pos); sci_set_selection_end(editor->sci, pos + text_len); editor_do_comment(editor, -1, TRUE, FALSE, FALSE); /* set the current position to the start of the first inserted line */ pos += strlen(co); /* on multi line comment jump to the next line, otherwise add the length of added indentation */ if (have_multiline_comment) pos += 1; else pos += strlen(indent); sci_set_current_position(editor->sci, pos, TRUE); /* reset the selection */ sci_set_anchor(editor->sci, pos); sci_end_undo_action(editor->sci); } /* Note: If the editor is pending a redraw, set document::scroll_percent instead. * Scroll the view to make line appear at percent_of_view. * line can be -1 to use the current position. */ void editor_scroll_to_line(GeanyEditor *editor, gint line, gfloat percent_of_view) { gint los; GtkWidget *wid; g_return_if_fail(editor != NULL); wid = GTK_WIDGET(editor->sci); if (! gtk_widget_get_window(wid) || ! gdk_window_is_viewable(gtk_widget_get_window(wid))) return; /* prevent gdk_window_scroll warning */ if (line == -1) line = sci_get_current_line(editor->sci); /* sci 'visible line' != doc line number because of folding and line wrapping */ /* calling SCI_VISIBLEFROMDOCLINE for line is more accurate than calling * SCI_DOCLINEFROMVISIBLE for vis1. */ line = SSM(editor->sci, SCI_VISIBLEFROMDOCLINE, line, 0); los = SSM(editor->sci, SCI_LINESONSCREEN, 0, 0); line = line - los * percent_of_view; SSM(editor->sci, SCI_SETFIRSTVISIBLELINE, line, 0); sci_scroll_caret(editor->sci); /* needed for horizontal scrolling */ } /* creates and inserts one tab or whitespace of the amount of the tab width */ void editor_insert_alternative_whitespace(GeanyEditor *editor) { gchar *text; GeanyIndentPrefs iprefs = *editor_get_indent_prefs(editor); g_return_if_fail(editor != NULL); switch (iprefs.type) { case GEANY_INDENT_TYPE_TABS: iprefs.type = GEANY_INDENT_TYPE_SPACES; break; case GEANY_INDENT_TYPE_SPACES: case GEANY_INDENT_TYPE_BOTH: /* most likely we want a tab */ iprefs.type = GEANY_INDENT_TYPE_TABS; break; } text = get_whitespace(&iprefs, iprefs.width); sci_add_text(editor->sci, text); g_free(text); } void editor_select_word(GeanyEditor *editor) { gint pos; gint start; gint end; g_return_if_fail(editor != NULL); pos = SSM(editor->sci, SCI_GETCURRENTPOS, 0, 0); start = sci_word_start_position(editor->sci, pos, TRUE); end = sci_word_end_position(editor->sci, pos, TRUE); if (start == end) /* caret in whitespaces sequence */ { /* look forward but reverse the selection direction, * so the caret end up stay as near as the original position. */ end = sci_word_end_position(editor->sci, pos, FALSE); start = sci_word_end_position(editor->sci, end, TRUE); if (start == end) return; } sci_set_selection(editor->sci, start, end); } /* extra_line is for selecting the cursor line (or anchor line) at the bottom of a selection, * when those lines have no selection (cursor at start of line). */ void editor_select_lines(GeanyEditor *editor, gboolean extra_line) { gint start, end, line; g_return_if_fail(editor != NULL); start = sci_get_selection_start(editor->sci); end = sci_get_selection_end(editor->sci); /* check if whole lines are already selected */ if (! extra_line && start != end && sci_get_col_from_position(editor->sci, start) == 0 && sci_get_col_from_position(editor->sci, end) == 0) return; line = sci_get_line_from_position(editor->sci, start); start = sci_get_position_from_line(editor->sci, line); line = sci_get_line_from_position(editor->sci, end); end = sci_get_position_from_line(editor->sci, line + 1); sci_set_selection(editor->sci, start, end); } static gboolean sci_is_blank_line(ScintillaObject *sci, gint line) { return sci_get_line_indent_position(sci, line) == sci_get_line_end_position(sci, line); } /* Returns first line of paragraph for GTK_DIR_UP, line after paragraph * ends for GTK_DIR_DOWN or -1 if called on an empty line. */ static gint find_paragraph_stop(GeanyEditor *editor, gint line, gint direction) { gint step; ScintillaObject *sci = editor->sci; /* first check current line and return -1 if it is empty to skip creating of a selection */ if (sci_is_blank_line(sci, line)) return -1; if (direction == GTK_DIR_UP) step = -1; else step = 1; while (TRUE) { line += step; if (line == -1) { /* start of document */ line = 0; break; } if (line == sci_get_line_count(sci)) break; if (sci_is_blank_line(sci, line)) { /* return line paragraph starts on */ if (direction == GTK_DIR_UP) line++; break; } } return line; } void editor_select_paragraph(GeanyEditor *editor) { gint pos_start, pos_end, line_start, line_found; g_return_if_fail(editor != NULL); line_start = sci_get_current_line(editor->sci); line_found = find_paragraph_stop(editor, line_start, GTK_DIR_UP); if (line_found == -1) return; pos_start = SSM(editor->sci, SCI_POSITIONFROMLINE, line_found, 0); line_found = find_paragraph_stop(editor, line_start, GTK_DIR_DOWN); pos_end = SSM(editor->sci, SCI_POSITIONFROMLINE, line_found, 0); sci_set_selection(editor->sci, pos_start, pos_end); } /* Returns first line of block for GTK_DIR_UP, line after block * ends for GTK_DIR_DOWN or -1 if called on an empty line. */ static gint find_block_stop(GeanyEditor *editor, gint line, gint direction) { gint step, ind; ScintillaObject *sci = editor->sci; /* first check current line and return -1 if it is empty to skip creating of a selection */ if (sci_is_blank_line(sci, line)) return -1; if (direction == GTK_DIR_UP) step = -1; else step = 1; ind = sci_get_line_indentation(sci, line); while (TRUE) { line += step; if (line == -1) { /* start of document */ line = 0; break; } if (line == sci_get_line_count(sci)) break; if (sci_get_line_indentation(sci, line) != ind || sci_is_blank_line(sci, line)) { /* return line block starts on */ if (direction == GTK_DIR_UP) line++; break; } } return line; } void editor_select_indent_block(GeanyEditor *editor) { gint pos_start, pos_end, line_start, line_found; g_return_if_fail(editor != NULL); line_start = sci_get_current_line(editor->sci); line_found = find_block_stop(editor, line_start, GTK_DIR_UP); if (line_found == -1) return; pos_start = SSM(editor->sci, SCI_POSITIONFROMLINE, line_found, 0); line_found = find_block_stop(editor, line_start, GTK_DIR_DOWN); pos_end = SSM(editor->sci, SCI_POSITIONFROMLINE, line_found, 0); sci_set_selection(editor->sci, pos_start, pos_end); } /* simple indentation to indent the current line with the same indent as the previous one */ static void smart_line_indentation(GeanyEditor *editor, gint first_line, gint last_line) { gint i, sel_start = 0, sel_end = 0; /* get previous line and use it for read_indent to use that line * (otherwise it would fail on a line only containing "{" in advanced indentation mode) */ read_indent(editor, sci_get_position_from_line(editor->sci, first_line - 1)); for (i = first_line; i <= last_line; i++) { /* skip the first line or if the indentation of the previous and current line are equal */ if (i == 0 || SSM(editor->sci, SCI_GETLINEINDENTATION, i - 1, 0) == SSM(editor->sci, SCI_GETLINEINDENTATION, i, 0)) continue; sel_start = SSM(editor->sci, SCI_POSITIONFROMLINE, i, 0); sel_end = SSM(editor->sci, SCI_GETLINEINDENTPOSITION, i, 0); if (sel_start < sel_end) { sci_set_selection(editor->sci, sel_start, sel_end); sci_replace_sel(editor->sci, ""); } sci_insert_text(editor->sci, sel_start, indent); } } /* simple indentation to indent the current line with the same indent as the previous one */ void editor_smart_line_indentation(GeanyEditor *editor) { gint first_line, last_line; gint first_sel_start, first_sel_end; ScintillaObject *sci; g_return_if_fail(editor != NULL); sci = editor->sci; first_sel_start = sci_get_selection_start(sci); first_sel_end = sci_get_selection_end(sci); first_line = sci_get_line_from_position(sci, first_sel_start); /* Find the last line with chars selected (not EOL char) */ last_line = sci_get_line_from_position(sci, first_sel_end - editor_get_eol_char_len(editor)); last_line = MAX(first_line, last_line); sci_start_undo_action(sci); smart_line_indentation(editor, first_line, last_line); /* set cursor position if there was no selection */ if (first_sel_start == first_sel_end) { gint indent_pos = SSM(sci, SCI_GETLINEINDENTPOSITION, first_line, 0); /* use indent position as user may wish to change indentation afterwards */ sci_set_current_position(sci, indent_pos, FALSE); } else { /* fully select all the lines affected */ sci_set_selection_start(sci, sci_get_position_from_line(sci, first_line)); sci_set_selection_end(sci, sci_get_position_from_line(sci, last_line + 1)); } sci_end_undo_action(sci); } /* increase / decrease current line or selection by one space */ void editor_indentation_by_one_space(GeanyEditor *editor, gint pos, gboolean decrease) { gint i, first_line, last_line, line_start, indentation_end, count = 0; gint sel_start, sel_end, first_line_offset = 0; g_return_if_fail(editor != NULL); sel_start = sci_get_selection_start(editor->sci); sel_end = sci_get_selection_end(editor->sci); first_line = sci_get_line_from_position(editor->sci, sel_start); /* Find the last line with chars selected (not EOL char) */ last_line = sci_get_line_from_position(editor->sci, sel_end - editor_get_eol_char_len(editor)); last_line = MAX(first_line, last_line); if (pos == -1) pos = sel_start; sci_start_undo_action(editor->sci); for (i = first_line; i <= last_line; i++) { indentation_end = SSM(editor->sci, SCI_GETLINEINDENTPOSITION, i, 0); if (decrease) { line_start = SSM(editor->sci, SCI_POSITIONFROMLINE, i, 0); /* searching backwards for a space to remove */ while (sci_get_char_at(editor->sci, indentation_end) != ' ' && indentation_end > line_start) indentation_end--; if (sci_get_char_at(editor->sci, indentation_end) == ' ') { sci_set_selection(editor->sci, indentation_end, indentation_end + 1); sci_replace_sel(editor->sci, ""); count--; if (i == first_line) first_line_offset = -1; } } else { sci_insert_text(editor->sci, indentation_end, " "); count++; if (i == first_line) first_line_offset = 1; } } /* set cursor position */ if (sel_start < sel_end) { gint start = sel_start + first_line_offset; if (first_line_offset < 0) start = MAX(sel_start + first_line_offset, SSM(editor->sci, SCI_POSITIONFROMLINE, first_line, 0)); sci_set_selection_start(editor->sci, start); sci_set_selection_end(editor->sci, sel_end + count); } else sci_set_current_position(editor->sci, pos + count, FALSE); sci_end_undo_action(editor->sci); } void editor_finalize(void) { scintilla_release_resources(); } /* wordchars: NULL or a string containing characters to match a word. * Returns: the current selection or the current word. * * Passing NULL as wordchars is NOT the same as passing GEANY_WORDCHARS: NULL means * using Scintillas's word boundaries. */ gchar *editor_get_default_selection(GeanyEditor *editor, gboolean use_current_word, const gchar *wordchars) { gchar *s = NULL; g_return_val_if_fail(editor != NULL, NULL); if (sci_get_lines_selected(editor->sci) == 1) s = sci_get_selection_contents(editor->sci); else if (sci_get_lines_selected(editor->sci) == 0 && use_current_word) { /* use the word at current cursor position */ gchar word[GEANY_MAX_WORD_LENGTH]; if (wordchars != NULL) editor_find_current_word(editor, -1, word, sizeof(word), wordchars); else editor_find_current_word_sciwc(editor, -1, word, sizeof(word)); if (word[0] != '\0') s = g_strdup(word); } return s; } /* Note: Usually the line should be made visible (not folded) before calling this. * Returns: TRUE if line is/will be displayed to the user, or FALSE if it is * outside the *vertical* view. * Warning: You may need horizontal scrolling to make the cursor visible - so always call * sci_scroll_caret() when this returns TRUE. */ gboolean editor_line_in_view(GeanyEditor *editor, gint line) { gint vis1, los; g_return_val_if_fail(editor != NULL, FALSE); /* If line is wrapped the result may occur on another virtual line than the first and may be * still hidden, so increase the line number to check for the next document line */ if (SSM(editor->sci, SCI_WRAPCOUNT, line, 0) > 1) line++; line = SSM(editor->sci, SCI_VISIBLEFROMDOCLINE, line, 0); /* convert to visible line number */ vis1 = SSM(editor->sci, SCI_GETFIRSTVISIBLELINE, 0, 0); los = SSM(editor->sci, SCI_LINESONSCREEN, 0, 0); return (line >= vis1 && line < vis1 + los); } /* If the current line is outside the current view window, scroll the line * so it appears at percent_of_view. */ void editor_display_current_line(GeanyEditor *editor, gfloat percent_of_view) { gint line; g_return_if_fail(editor != NULL); line = sci_get_current_line(editor->sci); /* unfold maybe folded results */ sci_ensure_line_is_visible(editor->sci, line); /* scroll the line if it's off screen */ if (! editor_line_in_view(editor, line)) editor->scroll_percent = percent_of_view; else sci_scroll_caret(editor->sci); /* may need horizontal scrolling */ } /* * Deletes all currently set indicators in the @a editor window. * Error indicators (red squiggly underlines) and usual line markers are removed. * * @param editor The editor to operate on. */ void editor_indicator_clear_errors(GeanyEditor *editor) { editor_indicator_clear(editor, GEANY_INDICATOR_ERROR); sci_marker_delete_all(editor->sci, 0); /* remove the yellow error line marker */ } /** * Deletes all currently set indicators matching @a indic in the @a editor window. * * @param editor The editor to operate on. * @param indic The indicator number to clear, this is a value of @ref GeanyIndicator. * * @since 0.16 */ GEANY_API_SYMBOL void editor_indicator_clear(GeanyEditor *editor, gint indic) { glong last_pos; g_return_if_fail(editor != NULL); last_pos = sci_get_length(editor->sci); if (last_pos > 0) { sci_indicator_set(editor->sci, indic); sci_indicator_clear(editor->sci, 0, last_pos); } } /** * Sets an indicator @a indic on @a line. * Whitespace at the start and the end of the line is not marked. * * @param editor The editor to operate on. * @param indic The indicator number to use, this is a value of @ref GeanyIndicator. * @param line The line number which should be marked. * * @since 0.16 */ GEANY_API_SYMBOL void editor_indicator_set_on_line(GeanyEditor *editor, gint indic, gint line) { gint start, end; guint i = 0, len; gchar *linebuf; g_return_if_fail(editor != NULL); g_return_if_fail(line >= 0); start = sci_get_position_from_line(editor->sci, line); end = sci_get_position_from_line(editor->sci, line + 1); /* skip blank lines */ if ((start + 1) == end || start > end || (sci_get_line_end_position(editor->sci, line) - start) == 0) { return; } len = end - start; linebuf = sci_get_line(editor->sci, line); /* don't set the indicator on whitespace */ while (isspace(linebuf[i])) i++; while (len > 1 && len > i && isspace(linebuf[len - 1])) { len--; end--; } g_free(linebuf); editor_indicator_set_on_range(editor, indic, start + i, end); } /** * Sets an indicator on the range specified by @a start and @a end. * No error checking or whitespace removal is performed, this should be done by the calling * function if necessary. * * @param editor The editor to operate on. * @param indic The indicator number to use, this is a value of @ref GeanyIndicator. * @param start The starting position for the marker. * @param end The ending position for the marker. * * @since 0.16 */ GEANY_API_SYMBOL void editor_indicator_set_on_range(GeanyEditor *editor, gint indic, gint start, gint end) { g_return_if_fail(editor != NULL); if (start >= end) return; sci_indicator_set(editor->sci, indic); sci_indicator_fill(editor->sci, start, end - start); } /* Inserts the given colour (format should be #...), if there is a selection starting with 0x... * the replacement will also start with 0x... */ void editor_insert_color(GeanyEditor *editor, const gchar *colour) { g_return_if_fail(editor != NULL); if (sci_has_selection(editor->sci)) { gint start = sci_get_selection_start(editor->sci); const gchar *replacement = colour; if (sci_get_char_at(editor->sci, start) == '0' && sci_get_char_at(editor->sci, start + 1) == 'x') { gint end = sci_get_selection_end(editor->sci); sci_set_selection_start(editor->sci, start + 2); /* we need to also re-set the selection end in case the anchor was located before * the cursor, since set_selection_start() always moves the cursor, not the anchor */ sci_set_selection_end(editor->sci, end); replacement++; /* skip the leading "0x" */ } else if (sci_get_char_at(editor->sci, start - 1) == '#') { /* double clicking something like #00ffff may only select 00ffff because of wordchars */ replacement++; /* so skip the '#' to only replace the colour value */ } sci_replace_sel(editor->sci, replacement); } else sci_add_text(editor->sci, colour); } /** * Retrieves the end of line characters mode (LF, CR/LF, CR) in the given editor. * If @a editor is @c NULL, the default end of line characters are used. * * @param editor @nullable The editor to operate on, or @c NULL to query the default value. * @return The used end of line characters mode. * * @since 0.20 */ GEANY_API_SYMBOL gint editor_get_eol_char_mode(GeanyEditor *editor) { gint mode = file_prefs.default_eol_character; if (editor != NULL) mode = sci_get_eol_mode(editor->sci); return mode; } /** * Retrieves the localized name (for displaying) of the used end of line characters * (LF, CR/LF, CR) in the given editor. * If @a editor is @c NULL, the default end of line characters are used. * * @param editor @nullable The editor to operate on, or @c NULL to query the default value. * @return The name of the end of line characters. * * @since 0.19 */ GEANY_API_SYMBOL const gchar *editor_get_eol_char_name(GeanyEditor *editor) { gint mode = file_prefs.default_eol_character; if (editor != NULL) mode = sci_get_eol_mode(editor->sci); return utils_get_eol_name(mode); } /** * Retrieves the length of the used end of line characters (LF, CR/LF, CR) in the given editor. * If @a editor is @c NULL, the default end of line characters are used. * The returned value is 1 for CR and LF and 2 for CR/LF. * * @param editor @nullable The editor to operate on, or @c NULL to query the default value. * @return The length of the end of line characters. * * @since 0.19 */ GEANY_API_SYMBOL gint editor_get_eol_char_len(GeanyEditor *editor) { gint mode = file_prefs.default_eol_character; if (editor != NULL) mode = sci_get_eol_mode(editor->sci); switch (mode) { case SC_EOL_CRLF: return 2; break; default: return 1; break; } } /** * Retrieves the used end of line characters (LF, CR/LF, CR) in the given editor. * If @a editor is @c NULL, the default end of line characters are used. * The returned value is either "\n", "\r\n" or "\r". * * @param editor @nullable The editor to operate on, or @c NULL to query the default value. * @return The end of line characters. * * @since 0.19 */ GEANY_API_SYMBOL const gchar *editor_get_eol_char(GeanyEditor *editor) { gint mode = file_prefs.default_eol_character; if (editor != NULL) mode = sci_get_eol_mode(editor->sci); return utils_get_eol_char(mode); } static void fold_all(GeanyEditor *editor, gboolean want_fold) { gint lines, first, i; if (editor == NULL || ! editor_prefs.folding) return; lines = sci_get_line_count(editor->sci); first = sci_get_first_visible_line(editor->sci); for (i = 0; i < lines; i++) { gint level = sci_get_fold_level(editor->sci, i); if (level & SC_FOLDLEVELHEADERFLAG) { if (sci_get_fold_expanded(editor->sci, i) == want_fold) sci_toggle_fold(editor->sci, i); } } editor_scroll_to_line(editor, first, 0.0F); } void editor_unfold_all(GeanyEditor *editor) { fold_all(editor, FALSE); } void editor_fold_all(GeanyEditor *editor) { fold_all(editor, TRUE); } void editor_replace_tabs(GeanyEditor *editor, gboolean ignore_selection) { gint anchor_pos, caret_pos; struct Sci_TextToFind ttf; g_return_if_fail(editor != NULL); sci_start_undo_action(editor->sci); if (sci_has_selection(editor->sci) && !ignore_selection) { ttf.chrg.cpMin = sci_get_selection_start(editor->sci); ttf.chrg.cpMax = sci_get_selection_end(editor->sci); } else { ttf.chrg.cpMin = 0; ttf.chrg.cpMax = sci_get_length(editor->sci); } ttf.lpstrText = (gchar*) "\t"; anchor_pos = SSM(editor->sci, SCI_GETANCHOR, 0, 0); caret_pos = sci_get_current_position(editor->sci); while (TRUE) { gint search_pos, pos_in_line, current_tab_true_length; gint tab_len; gchar *tab_str; search_pos = sci_find_text(editor->sci, SCFIND_MATCHCASE, &ttf); if (search_pos == -1) break; tab_len = sci_get_tab_width(editor->sci); pos_in_line = sci_get_col_from_position(editor->sci, search_pos); current_tab_true_length = tab_len - (pos_in_line % tab_len); tab_str = g_strnfill(current_tab_true_length, ' '); sci_set_target_start(editor->sci, search_pos); sci_set_target_end(editor->sci, search_pos + 1); sci_replace_target(editor->sci, tab_str, FALSE); /* next search starts after replacement */ ttf.chrg.cpMin = search_pos + current_tab_true_length - 1; /* update end of range now text has changed */ ttf.chrg.cpMax += current_tab_true_length - 1; g_free(tab_str); if (anchor_pos > search_pos) anchor_pos += current_tab_true_length - 1; if (caret_pos > search_pos) caret_pos += current_tab_true_length - 1; } sci_set_selection(editor->sci, anchor_pos, caret_pos); sci_end_undo_action(editor->sci); } /* Replaces all occurrences all spaces of the length of a given tab_width, * optionally restricting the search to the current selection. */ void editor_replace_spaces(GeanyEditor *editor, gboolean ignore_selection) { gint search_pos; gint anchor_pos, caret_pos; static gdouble tab_len_f = -1.0; /* keep the last used value */ gint tab_len; gchar *text; struct Sci_TextToFind ttf; g_return_if_fail(editor != NULL); if (tab_len_f < 0.0) tab_len_f = sci_get_tab_width(editor->sci); if (! dialogs_show_input_numeric( _("Enter Tab Width"), _("Enter the amount of spaces which should be replaced by a tab character."), &tab_len_f, 1, 100, 1)) { return; } tab_len = (gint) tab_len_f; text = g_strnfill(tab_len, ' '); sci_start_undo_action(editor->sci); if (sci_has_selection(editor->sci) && !ignore_selection) { ttf.chrg.cpMin = sci_get_selection_start(editor->sci); ttf.chrg.cpMax = sci_get_selection_end(editor->sci); } else { ttf.chrg.cpMin = 0; ttf.chrg.cpMax = sci_get_length(editor->sci); } ttf.lpstrText = text; anchor_pos = SSM(editor->sci, SCI_GETANCHOR, 0, 0); caret_pos = sci_get_current_position(editor->sci); while (TRUE) { search_pos = sci_find_text(editor->sci, SCFIND_MATCHCASE, &ttf); if (search_pos == -1) break; /* only replace indentation because otherwise we can mess up alignment */ if (search_pos > sci_get_line_indent_position(editor->sci, sci_get_line_from_position(editor->sci, search_pos))) { ttf.chrg.cpMin = search_pos + tab_len; continue; } sci_set_target_start(editor->sci, search_pos); sci_set_target_end(editor->sci, search_pos + tab_len); sci_replace_target(editor->sci, "\t", FALSE); ttf.chrg.cpMin = search_pos; /* update end of range now text has changed */ ttf.chrg.cpMax -= tab_len - 1; if (anchor_pos > search_pos) anchor_pos -= tab_len - 1; if (caret_pos > search_pos) caret_pos -= tab_len - 1; } sci_set_selection(editor->sci, anchor_pos, caret_pos); sci_end_undo_action(editor->sci); g_free(text); } void editor_strip_line_trailing_spaces(GeanyEditor *editor, gint line) { gint line_start = sci_get_position_from_line(editor->sci, line); gint line_end = sci_get_line_end_position(editor->sci, line); gint i = line_end - 1; gchar ch = sci_get_char_at(editor->sci, i); /* Diff hunks should keep trailing spaces */ if (editor->document->file_type->id == GEANY_FILETYPES_DIFF) return; while ((i >= line_start) && ((ch == ' ') || (ch == '\t'))) { i--; ch = sci_get_char_at(editor->sci, i); } if (i < (line_end - 1)) { sci_set_target_start(editor->sci, i + 1); sci_set_target_end(editor->sci, line_end); sci_replace_target(editor->sci, "", FALSE); } } void editor_strip_trailing_spaces(GeanyEditor *editor, gboolean ignore_selection) { gint start_line; gint end_line; gint line; if (sci_has_selection(editor->sci) && !ignore_selection) { gint selection_start = sci_get_selection_start(editor->sci); gint selection_end = sci_get_selection_end(editor->sci); start_line = sci_get_line_from_position(editor->sci, selection_start); end_line = sci_get_line_from_position(editor->sci, selection_end); if (sci_get_col_from_position(editor->sci, selection_end) > 0) end_line++; } else { start_line = 0; end_line = sci_get_line_count(editor->sci); } sci_start_undo_action(editor->sci); for (line = start_line; line < end_line; line++) { editor_strip_line_trailing_spaces(editor, line); } sci_end_undo_action(editor->sci); } void editor_ensure_final_newline(GeanyEditor *editor) { gint max_lines = sci_get_line_count(editor->sci); gboolean append_newline = (max_lines == 1); gint end_document = sci_get_position_from_line(editor->sci, max_lines); if (max_lines > 1) { append_newline = end_document > sci_get_position_from_line(editor->sci, max_lines - 1); } if (append_newline) { const gchar *eol = editor_get_eol_char(editor); sci_insert_text(editor->sci, end_document, eol); } } /* Similar to editor_set_font() but *only* sets the font, and doesn't take care * of updating properties that might depend on the font */ static void set_font(ScintillaObject *sci, const gchar *font) { gint style; gchar *font_name; PangoFontDescription *pfd; gdouble size; g_return_if_fail(sci); pfd = pango_font_description_from_string(font); size = pango_font_description_get_size(pfd) / (gdouble) PANGO_SCALE; font_name = g_strdup_printf("!%s", pango_font_description_get_family(pfd)); pango_font_description_free(pfd); for (style = 0; style <= STYLE_MAX; style++) sci_set_font_fractional(sci, style, font_name, size); g_free(font_name); } void editor_set_font(GeanyEditor *editor, const gchar *font) { g_return_if_fail(editor); set_font(editor->sci, font); update_margins(editor->sci); /* zoom to 100% to prevent confusion */ sci_zoom_off(editor->sci); } void editor_set_line_wrapping(GeanyEditor *editor, gboolean wrap) { g_return_if_fail(editor != NULL); editor->line_wrapping = wrap; sci_set_lines_wrapped(editor->sci, wrap); } /** Sets the indent type for @a editor. * @param editor Editor. * @param type Indent type. * * @since 0.16 */ GEANY_API_SYMBOL void editor_set_indent_type(GeanyEditor *editor, GeanyIndentType type) { editor_set_indent(editor, type, editor->indent_width); } /** Sets the indent width for @a editor. * @param editor Editor. * @param width New indent width. * * @since 1.27 (API 227) */ GEANY_API_SYMBOL void editor_set_indent_width(GeanyEditor *editor, gint width) { editor_set_indent(editor, editor->indent_type, width); } void editor_set_indent(GeanyEditor *editor, GeanyIndentType type, gint width) { const GeanyIndentPrefs *iprefs = editor_get_indent_prefs(editor); ScintillaObject *sci = editor->sci; gboolean use_tabs = type != GEANY_INDENT_TYPE_SPACES; editor->indent_type = type; editor->indent_width = width; sci_set_use_tabs(sci, use_tabs); if (type == GEANY_INDENT_TYPE_BOTH) { sci_set_tab_width(sci, iprefs->hard_tab_width); if (iprefs->hard_tab_width != 8) { static gboolean warn = TRUE; if (warn) ui_set_statusbar(TRUE, _("Warning: non-standard hard tab width: %d != 8!"), iprefs->hard_tab_width); warn = FALSE; } } else sci_set_tab_width(sci, width); SSM(sci, SCI_SETINDENT, width, 0); /* remove indent spaces on backspace, if using any spaces to indent */ SSM(sci, SCI_SETBACKSPACEUNINDENTS, editor_prefs.backspace_unindent && (type != GEANY_INDENT_TYPE_TABS), 0); } /* Convenience function for editor_goto_pos() to pass a line number. * line_no is 1 based */ gboolean editor_goto_line(GeanyEditor *editor, gint line_no, gboolean offset) { g_return_val_if_fail(editor, FALSE); gint line_count = sci_get_line_count(editor->sci); if (offset) line_no += sci_get_current_line(editor->sci) + 1; /* ensure line_no is in bounds and determine whether to set line marker */ gboolean set_marker = line_no > 0 && line_no < line_count; line_no = line_no <= 0 ? 0 : line_no >= line_count ? line_count - 1 : line_no - 1; gint pos = sci_get_position_from_line(editor->sci, line_no); return editor_goto_pos(editor, pos, set_marker); } /** Moves to position @a pos, switching to the document if necessary, * setting a marker if @a mark is set. * * @param editor Editor. * @param pos The position. * @param mark Whether to set a mark on the position. * @return @c TRUE if action has been performed, otherwise @c FALSE. * * @since 0.20 **/ GEANY_API_SYMBOL gboolean editor_goto_pos(GeanyEditor *editor, gint pos, gboolean mark) { g_return_val_if_fail(editor, FALSE); if (G_UNLIKELY(pos < 0)) return FALSE; if (mark) { gint line = sci_get_line_from_position(editor->sci, pos); /* mark the tag with the yellow arrow */ sci_marker_delete_all(editor->sci, 0); sci_set_marker_at_line(editor->sci, line, 0); } sci_goto_pos(editor->sci, pos, TRUE); editor->scroll_percent = 0.25F; /* switch to the page, via idle callback in case of batch-opening */ if (main_status.opening_session_files) document_show_tab_idle(editor->document); else document_show_tab(editor->document); return TRUE; } static gboolean on_editor_scroll_event(GtkWidget *widget, GdkEventScroll *event, gpointer user_data) { GeanyEditor *editor = user_data; /* we only handle up and down, leave the rest to Scintilla */ if (event->direction != GDK_SCROLL_UP && event->direction != GDK_SCROLL_DOWN) return FALSE; /* Handle scroll events if Alt is pressed and scroll whole pages instead of a * few lines only, maybe this could/should be done in Scintilla directly */ if (event->state & GDK_MOD1_MASK) { sci_send_command(editor->sci, (event->direction == GDK_SCROLL_DOWN) ? SCI_PAGEDOWN : SCI_PAGEUP); return TRUE; } else if (event->state & GDK_SHIFT_MASK) { gint amount = (event->direction == GDK_SCROLL_DOWN) ? 8 : -8; sci_scroll_columns(editor->sci, amount); return TRUE; } return FALSE; /* let Scintilla handle all other cases */ } static gboolean editor_check_colourise(GeanyEditor *editor) { GeanyDocument *doc = editor->document; if (!doc->priv->colourise_needed) return FALSE; doc->priv->colourise_needed = FALSE; sci_colourise(editor->sci, 0, -1); /* now that the current document is colourised, fold points are now accurate, * so force an update of the current function/tag. */ symbols_get_current_function(NULL, NULL); ui_update_statusbar(NULL, -1); return TRUE; } /* We only want to colourise just before drawing, to save startup time and * prevent unnecessary recolouring other documents after one is saved. * Really we want a "draw" signal but there doesn't seem to be one (expose is too late, * and "show" doesn't work). */ static gboolean on_editor_focus_in(GtkWidget *widget, GdkEventFocus *event, gpointer user_data) { GeanyEditor *editor = user_data; editor_check_colourise(editor); return FALSE; } static gboolean on_editor_draw(GtkWidget *widget, cairo_t *cr, gpointer user_data) { GeanyEditor *editor = user_data; /* This is just to catch any uncolourised documents being drawn that didn't receive focus * for some reason, maybe it's not necessary but just in case. */ editor_check_colourise(editor); return FALSE; } static void setup_sci_keys(ScintillaObject *sci) { /* disable some Scintilla keybindings to be able to redefine them cleanly */ sci_clear_cmdkey(sci, 'A' | (SCMOD_CTRL << 16)); /* select all */ sci_clear_cmdkey(sci, 'D' | (SCMOD_CTRL << 16)); /* duplicate */ sci_clear_cmdkey(sci, 'T' | (SCMOD_CTRL << 16)); /* line transpose */ sci_clear_cmdkey(sci, 'T' | (SCMOD_CTRL << 16) | (SCMOD_SHIFT << 16)); /* line copy */ sci_clear_cmdkey(sci, 'L' | (SCMOD_CTRL << 16)); /* line cut */ sci_clear_cmdkey(sci, 'L' | (SCMOD_CTRL << 16) | (SCMOD_SHIFT << 16)); /* line delete */ sci_clear_cmdkey(sci, SCK_DELETE | (SCMOD_CTRL << 16) | (SCMOD_SHIFT << 16)); /* line to end delete */ sci_clear_cmdkey(sci, SCK_BACK | (SCMOD_CTRL << 16) | (SCMOD_SHIFT << 16)); /* line to beginning delete */ sci_clear_cmdkey(sci, '/' | (SCMOD_CTRL << 16)); /* Previous word part */ sci_clear_cmdkey(sci, '\\' | (SCMOD_CTRL << 16)); /* Next word part */ sci_clear_cmdkey(sci, SCK_UP | (SCMOD_CTRL << 16)); /* scroll line up */ sci_clear_cmdkey(sci, SCK_DOWN | (SCMOD_CTRL << 16)); /* scroll line down */ sci_clear_cmdkey(sci, SCK_HOME); /* line start */ sci_clear_cmdkey(sci, SCK_END); /* line end */ sci_clear_cmdkey(sci, SCK_END | (SCMOD_ALT << 16)); /* visual line end */ if (editor_prefs.use_gtk_word_boundaries) { /* use GtkEntry-like word boundaries */ sci_assign_cmdkey(sci, SCK_RIGHT | (SCMOD_CTRL << 16), SCI_WORDRIGHTEND); sci_assign_cmdkey(sci, SCK_RIGHT | (SCMOD_CTRL << 16) | (SCMOD_SHIFT << 16), SCI_WORDRIGHTENDEXTEND); sci_assign_cmdkey(sci, SCK_DELETE | (SCMOD_CTRL << 16), SCI_DELWORDRIGHTEND); } sci_assign_cmdkey(sci, SCK_UP | (SCMOD_ALT << 16), SCI_LINESCROLLUP); sci_assign_cmdkey(sci, SCK_DOWN | (SCMOD_ALT << 16), SCI_LINESCROLLDOWN); sci_assign_cmdkey(sci, SCK_UP | (SCMOD_CTRL << 16), SCI_PARAUP); sci_assign_cmdkey(sci, SCK_UP | (SCMOD_CTRL << 16) | (SCMOD_SHIFT << 16), SCI_PARAUPEXTEND); sci_assign_cmdkey(sci, SCK_DOWN | (SCMOD_CTRL << 16), SCI_PARADOWN); sci_assign_cmdkey(sci, SCK_DOWN | (SCMOD_CTRL << 16) | (SCMOD_SHIFT << 16), SCI_PARADOWNEXTEND); sci_clear_cmdkey(sci, SCK_BACK | (SCMOD_ALT << 16)); /* clear Alt-Backspace (Undo) */ } /* registers a Scintilla image from a named icon from the theme */ static gboolean register_named_icon(ScintillaObject *sci, guint id, const gchar *name) { GError *error = NULL; GdkPixbuf *pixbuf; gint n_channels, rowstride, width, height; gint size; gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &size, NULL); pixbuf = gtk_icon_theme_load_icon(gtk_icon_theme_get_default(), name, size, 0, &error); if (! pixbuf) { g_warning("failed to load icon '%s': %s", name, error->message); g_error_free(error); return FALSE; } n_channels = gdk_pixbuf_get_n_channels(pixbuf); rowstride = gdk_pixbuf_get_rowstride(pixbuf); width = gdk_pixbuf_get_width(pixbuf); height = gdk_pixbuf_get_height(pixbuf); if (gdk_pixbuf_get_bits_per_sample(pixbuf) != 8 || ! gdk_pixbuf_get_has_alpha(pixbuf) || n_channels != 4 || rowstride != width * n_channels) { g_warning("incompatible image data for icon '%s'", name); g_object_unref(pixbuf); return FALSE; } SSM(sci, SCI_RGBAIMAGESETWIDTH, width, 0); SSM(sci, SCI_RGBAIMAGESETHEIGHT, height, 0); SSM(sci, SCI_REGISTERRGBAIMAGE, id, (sptr_t)gdk_pixbuf_get_pixels(pixbuf)); g_object_unref(pixbuf); return TRUE; } /* Create new editor widget (scintilla). * @note The @c "sci-notify" signal is connected separately. */ static ScintillaObject *create_new_sci(GeanyEditor *editor) { ScintillaObject *sci; int rectangular_selection_modifier; guint i; sci = SCINTILLA(scintilla_new()); /* Scintilla doesn't support RTL languages properly and is primarily * intended to be used with LTR source code, so override the * GTK+ default text direction for the Scintilla widget. */ gtk_widget_set_direction(GTK_WIDGET(sci), GTK_TEXT_DIR_LTR); gtk_widget_show(GTK_WIDGET(sci)); sci_set_codepage(sci, SC_CP_UTF8); /*SSM(sci, SCI_SETWRAPSTARTINDENT, 4, 0);*/ /* disable scintilla provided popup menu */ sci_use_popup(sci, FALSE); setup_sci_keys(sci); sci_set_lines_wrapped(sci, editor->line_wrapping); sci_set_caret_policy_x(sci, CARET_JUMPS | CARET_EVEN, 0); /* Y policy is set in editor_apply_update_prefs() */ SSM(sci, SCI_AUTOCSETSEPARATOR, '\n', 0); SSM(sci, SCI_SETSCROLLWIDTHTRACKING, 1, 0); /* tag autocompletion images */ for (i = 0; i < TM_N_ICONS; i++) { const gchar *icon_name = symbols_get_icon_name(i); register_named_icon(sci, i + 1, icon_name); } /* necessary for column mode editing, implemented in Scintilla since 2.0 */ SSM(sci, SCI_SETADDITIONALSELECTIONTYPING, 1, 0); /* rectangular selection modifier for creating rectangular selections with the mouse. * We use the historical Scintilla values by default. */ #ifdef G_OS_WIN32 rectangular_selection_modifier = SCMOD_ALT; #else rectangular_selection_modifier = SCMOD_CTRL; #endif SSM(sci, SCI_SETRECTANGULARSELECTIONMODIFIER, rectangular_selection_modifier, 0); /* virtual space */ SSM(sci, SCI_SETVIRTUALSPACEOPTIONS, editor_prefs.show_virtual_space, 0); /* input method editor's candidate window behaviour */ SSM(sci, SCI_SETIMEINTERACTION, editor_prefs.ime_interaction, 0); /* only connect signals if this is for the document notebook, not split window */ if (editor->sci == NULL) { g_signal_connect(sci, "button-press-event", G_CALLBACK(on_editor_button_press_event), editor); g_signal_connect(sci, "scroll-event", G_CALLBACK(on_editor_scroll_event), editor); g_signal_connect(sci, "motion-notify-event", G_CALLBACK(on_motion_event), NULL); g_signal_connect(sci, "focus-in-event", G_CALLBACK(on_editor_focus_in), editor); g_signal_connect(sci, "draw", G_CALLBACK(on_editor_draw), editor); } return sci; } /** Creates a new Scintilla @c GtkWidget based on the settings for @a editor. * @param editor Editor settings. * @return @transfer{floating} The new widget. * * @since 0.15 **/ GEANY_API_SYMBOL ScintillaObject *editor_create_widget(GeanyEditor *editor) { const GeanyIndentPrefs *iprefs = get_default_indent_prefs(); ScintillaObject *old, *sci; GeanyIndentType old_indent_type = editor->indent_type; gint old_indent_width = editor->indent_width; /* temporarily change editor to use the new sci widget */ old = editor->sci; sci = create_new_sci(editor); editor->sci = sci; editor_set_indent(editor, iprefs->type, iprefs->width); set_font(editor->sci, interface_prefs.editor_font); editor_apply_update_prefs(editor); /* if editor already had a widget, restore it */ if (old) { editor->indent_type = old_indent_type; editor->indent_width = old_indent_width; editor->sci = old; } return sci; } GeanyEditor *editor_create(GeanyDocument *doc) { const GeanyIndentPrefs *iprefs = get_default_indent_prefs(); GeanyEditor *editor = g_new0(GeanyEditor, 1); editor->document = doc; doc->editor = editor; /* needed in case some editor functions/callbacks expect it */ editor->auto_indent = (iprefs->auto_indent_mode != GEANY_AUTOINDENT_NONE); editor->line_wrapping = get_project_pref(line_wrapping); editor->scroll_percent = -1.0F; editor->line_breaking = FALSE; editor->sci = editor_create_widget(editor); return editor; } /* in case we need to free some fields in future */ void editor_destroy(GeanyEditor *editor) { g_free(editor); } static void on_document_save(GObject *obj, GeanyDocument *doc) { gchar *f = g_build_filename(app->configdir, "snippets.conf", NULL); if (utils_str_equal(doc->real_path, f)) { /* reload snippets */ editor_snippets_free(); editor_snippets_init(); } g_free(f); } gboolean editor_complete_word_part(GeanyEditor *editor) { gchar *entry; g_return_val_if_fail(editor, FALSE); if (!SSM(editor->sci, SCI_AUTOCACTIVE, 0, 0)) return FALSE; entry = sci_get_string(editor->sci, SCI_AUTOCGETCURRENTTEXT, 0); /* if no word part, complete normally */ if (!check_partial_completion(editor, entry)) SSM(editor->sci, SCI_AUTOCCOMPLETE, 0, 0); g_free(entry); return TRUE; } void editor_init(void) { static GeanyIndentPrefs indent_prefs; gchar *f; memset(&editor_prefs, 0, sizeof(GeanyEditorPrefs)); memset(&indent_prefs, 0, sizeof(GeanyIndentPrefs)); editor_prefs.indentation = &indent_prefs; /* use g_signal_connect_after() to allow plugins connecting to the signal before the default * handler (on_editor_notify) is called */ g_signal_connect_after(geany_object, "editor-notify", G_CALLBACK(on_editor_notify), NULL); f = g_build_filename(app->configdir, "snippets.conf", NULL); ui_add_config_file_menu_item(f, NULL, NULL); g_free(f); g_signal_connect(geany_object, "document-save", G_CALLBACK(on_document_save), NULL); } /* TODO: Should these be user-defined instead of hard-coded? */ void editor_set_indentation_guides(GeanyEditor *editor) { gint mode; gint lexer; g_return_if_fail(editor != NULL); if (! editor_prefs.show_indent_guide) { sci_set_indentation_guides(editor->sci, SC_IV_NONE); return; } lexer = sci_get_lexer(editor->sci); switch (lexer) { /* Lines added/removed are prefixed with +/- characters, so * those lines will not be shown with any indentation guides. * It can be distracting that only a few of lines in a diff/patch * file will show the guides. */ case SCLEX_DIFF: mode = SC_IV_NONE; break; /* These languages use indentation for control blocks; the "look forward" method works * best here */ case SCLEX_PYTHON: case SCLEX_HASKELL: case SCLEX_MAKEFILE: case SCLEX_ASM: case SCLEX_SQL: case SCLEX_COBOL: case SCLEX_PROPERTIES: case SCLEX_FORTRAN: /* Is this the best option for Fortran? */ case SCLEX_CAML: mode = SC_IV_LOOKFORWARD; break; /* C-like (structured) languages benefit from the "look both" method */ case SCLEX_CPP: case SCLEX_HTML: case SCLEX_PHPSCRIPT: case SCLEX_XML: case SCLEX_PERL: case SCLEX_LATEX: case SCLEX_LUA: case SCLEX_PASCAL: case SCLEX_RUBY: case SCLEX_TCL: case SCLEX_F77: case SCLEX_CSS: case SCLEX_BASH: case SCLEX_VHDL: case SCLEX_FREEBASIC: case SCLEX_D: case SCLEX_OCTAVE: case SCLEX_RUST: mode = SC_IV_LOOKBOTH; break; default: mode = SC_IV_REAL; break; } sci_set_indentation_guides(editor->sci, mode); } /* Apply non-document prefs that can change in the Preferences dialog */ void editor_apply_update_prefs(GeanyEditor *editor) { ScintillaObject *sci; int caret_y_policy; g_return_if_fail(editor != NULL); if (main_status.quitting) return; sci = editor->sci; sci_set_mark_long_lines(sci, editor_get_long_line_type(), editor_get_long_line_column(), editor_prefs.long_line_color); /* update indent width, tab width */ editor_set_indent(editor, editor->indent_type, editor->indent_width); sci_set_tab_indents(sci, editor_prefs.use_tab_to_indent); sci_assign_cmdkey(sci, SCK_HOME | (SCMOD_SHIFT << 16), editor_prefs.smart_home_key ? SCI_VCHOMEEXTEND : SCI_HOMEEXTEND); sci_assign_cmdkey(sci, SCK_HOME | ((SCMOD_SHIFT | SCMOD_ALT) << 16), editor_prefs.smart_home_key ? SCI_VCHOMERECTEXTEND : SCI_HOMERECTEXTEND); sci_set_autoc_max_height(sci, editor_prefs.symbolcompletion_max_height); SSM(sci, SCI_AUTOCSETDROPRESTOFWORD, editor_prefs.completion_drops_rest_of_word, 0); editor_set_indentation_guides(editor); sci_set_visible_white_spaces(sci, editor_prefs.show_white_space); sci_set_visible_eols(sci, editor_prefs.show_line_endings); sci_set_symbol_margin(sci, editor_prefs.show_markers_margin); sci_set_line_numbers(sci, editor_prefs.show_linenumber_margin); sci_set_eol_representation_characters(sci, sci_get_eol_mode(sci)); sci_set_folding_margin_visible(sci, editor_prefs.folding); /* virtual space */ SSM(sci, SCI_SETVIRTUALSPACEOPTIONS, editor_prefs.show_virtual_space, 0); /* Change history */ guint change_history_mask; change_history_mask = SC_CHANGE_HISTORY_DISABLED; if (editor_prefs.change_history_markers) change_history_mask |= SC_CHANGE_HISTORY_ENABLED|SC_CHANGE_HISTORY_MARKERS; if (editor_prefs.change_history_indicators) change_history_mask |= SC_CHANGE_HISTORY_ENABLED|SC_CHANGE_HISTORY_INDICATORS; SSM(sci, SCI_SETCHANGEHISTORY, change_history_mask, 0); /* caret Y policy */ caret_y_policy = CARET_EVEN; if (editor_prefs.scroll_lines_around_cursor > 0) caret_y_policy |= CARET_SLOP | CARET_STRICT; sci_set_caret_policy_y(sci, caret_y_policy, editor_prefs.scroll_lines_around_cursor); /* (dis)allow scrolling past end of document */ sci_set_scroll_stop_at_last_line(sci, editor_prefs.scroll_stop_at_last_line); sci_set_scrollbar_mode(sci, editor_prefs.show_scrollbars); } /* This is for tab-indents, space aligns formatted code. Spaces should be preserved. */ static void change_tab_indentation(GeanyEditor *editor, gint line, gboolean increase) { ScintillaObject *sci = editor->sci; gint pos = sci_get_position_from_line(sci, line); if (increase) { sci_insert_text(sci, pos, "\t"); } else { if (sci_get_char_at(sci, pos) == '\t') { sci_set_selection(sci, pos, pos + 1); sci_replace_sel(sci, ""); } else /* remove spaces only if no tabs */ { gint width = sci_get_line_indentation(sci, line); width -= editor_get_indent_prefs(editor)->width; sci_set_line_indentation(sci, line, width); } } } static void editor_change_line_indent(GeanyEditor *editor, gint line, gboolean increase) { const GeanyIndentPrefs *iprefs = editor_get_indent_prefs(editor); ScintillaObject *sci = editor->sci; if (iprefs->type == GEANY_INDENT_TYPE_TABS) change_tab_indentation(editor, line, increase); else { gint width = sci_get_line_indentation(sci, line); width += increase ? iprefs->width : -iprefs->width; sci_set_line_indentation(sci, line, width); } } void editor_indent(GeanyEditor *editor, gboolean increase) { ScintillaObject *sci = editor->sci; gint caret_pos, caret_line, caret_offset, caret_indent_pos, caret_line_len; gint anchor_pos, anchor_line, anchor_offset, anchor_indent_pos, anchor_line_len; /* backup information needed to restore caret and anchor */ caret_pos = sci_get_current_position(sci); anchor_pos = SSM(sci, SCI_GETANCHOR, 0, 0); caret_line = sci_get_line_from_position(sci, caret_pos); anchor_line = sci_get_line_from_position(sci, anchor_pos); caret_offset = caret_pos - sci_get_position_from_line(sci, caret_line); anchor_offset = anchor_pos - sci_get_position_from_line(sci, anchor_line); caret_indent_pos = sci_get_line_indent_position(sci, caret_line); anchor_indent_pos = sci_get_line_indent_position(sci, anchor_line); caret_line_len = sci_get_line_length(sci, caret_line); anchor_line_len = sci_get_line_length(sci, anchor_line); if (sci_get_lines_selected(sci) <= 1) { editor_change_line_indent(editor, sci_get_current_line(sci), increase); } else { gint start, end; gint line, lstart, lend; editor_select_lines(editor, FALSE); start = sci_get_selection_start(sci); end = sci_get_selection_end(sci); lstart = sci_get_line_from_position(sci, start); lend = sci_get_line_from_position(sci, end); if (end == sci_get_length(sci)) lend++; /* for last line with text on it */ sci_start_undo_action(sci); for (line = lstart; line < lend; line++) { editor_change_line_indent(editor, line, increase); } sci_end_undo_action(sci); } /* restore caret and anchor position */ if (caret_pos >= caret_indent_pos) caret_offset += sci_get_line_length(sci, caret_line) - caret_line_len; if (anchor_pos >= anchor_indent_pos) anchor_offset += sci_get_line_length(sci, anchor_line) - anchor_line_len; SSM(sci, SCI_SETCURRENTPOS, sci_get_position_from_line(sci, caret_line) + caret_offset, 0); SSM(sci, SCI_SETANCHOR, sci_get_position_from_line(sci, anchor_line) + anchor_offset, 0); } /** Gets snippet by name. * * If @a editor is passed, returns a snippet specific to the document filetype. * If @a editor is @c NULL, returns a snippet from the default set. * * @param editor @nullable Editor or @c NULL. * @param snippet_name Snippet name. * @return @nullable snippet or @c NULL if it was not found. Must not be freed. */ GEANY_API_SYMBOL const gchar *editor_find_snippet(GeanyEditor *editor, const gchar *snippet_name) { const gchar *subhash_name = editor ? editor->document->file_type->name : "Default"; GHashTable *subhash = g_hash_table_lookup(snippet_hash, subhash_name); return subhash ? g_hash_table_lookup(subhash, snippet_name) : NULL; } /** Replaces all special sequences in @a snippet and inserts it at @a pos. * If you insert at the current position, consider calling @c sci_scroll_caret() * after this function. * @param editor . * @param pos . * @param snippet . */ GEANY_API_SYMBOL void editor_insert_snippet(GeanyEditor *editor, gint pos, const gchar *snippet) { GString *pattern; pattern = g_string_new(snippet); snippets_make_replacements(editor, pattern); editor_insert_text_block(editor, pattern->str, pos, -1, -1, TRUE); g_string_free(pattern, TRUE); } static void *copy_(void *src) { return src; } static void free_(void *doc) { } /** @gironly * Gets the GType of GeanyEditor * * @return the GeanyEditor type */ GEANY_API_SYMBOL GType editor_get_type (void); G_DEFINE_BOXED_TYPE(GeanyEditor, editor, copy_, free_); geany-2.0/src/Makefile.in0000644000175000017500000027355714514252335012262 00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ bin_PROGRAMS = geany$(EXEEXT) @ENABLE_BINRELOC_TRUE@am__append_1 = -Wl,-rpath='$$ORIGIN/../lib' @ENABLE_BINRELOC_TRUE@am__append_2 = prefix.c prefix.h @ENABLE_MAC_INTEGRATION_TRUE@am__append_3 = osx.c osx.h # build Geany for Windows (possibly on non-Windows systems -- cross-compile) @MINGW_TRUE@am__append_4 = \ @MINGW_TRUE@ -DGEANY_DATADIR=\"data\" \ @MINGW_TRUE@ -DGEANY_DOCDIR=\"\" \ @MINGW_TRUE@ -DGEANY_LIBDIR=\"\" \ @MINGW_TRUE@ -DGEANY_LIBEXECDIR=\"\" \ @MINGW_TRUE@ -DGEANY_LOCALEDIR=\"\" \ @MINGW_TRUE@ -DGEANY_PREFIX=\"\" @MINGW_TRUE@am__append_5 = geany_private.res @MINGW_TRUE@am__append_6 = win32.c win32.h @MINGW_TRUE@am__append_7 = -lole32 -lwsock32 -lcomdlg32 @MINGW_TRUE@am__append_8 = -mwindows -mms-bitfields -no-undefined @MINGW_TRUE@am__append_9 = -mwindows -mms-bitfields @MINGW_TRUE@am__append_10 = geany_private.res # build Geany for all other platforms @MINGW_FALSE@am__append_11 = \ @MINGW_FALSE@ -DGEANY_DATADIR=\""$(datadir)"\" \ @MINGW_FALSE@ -DGEANY_DOCDIR=\""$(docdir)"\" \ @MINGW_FALSE@ -DGEANY_LIBDIR=\""$(libdir)"\" \ @MINGW_FALSE@ -DGEANY_LIBEXECDIR=\""$(libexecdir)"\" \ @MINGW_FALSE@ -DGEANY_LOCALEDIR=\""$(localedir)"\" \ @MINGW_FALSE@ -DGEANY_PREFIX=\""$(prefix)"\" @MINGW_FALSE@am__append_12 = vte.c vte.h subdir = src ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx_17.m4 \ $(top_srcdir)/m4/geany-binreloc.m4 \ $(top_srcdir)/m4/geany-docutils.m4 \ $(top_srcdir)/m4/geany-doxygen.m4 \ $(top_srcdir)/m4/geany-gtk.m4 \ $(top_srcdir)/m4/geany-gtkdoc-header.m4 \ $(top_srcdir)/m4/geany-lib.m4 \ $(top_srcdir)/m4/geany-mac-integration.m4 \ $(top_srcdir)/m4/geany-mingw.m4 \ $(top_srcdir)/m4/geany-plugins.m4 \ $(top_srcdir)/m4/geany-prog-cxx.m4 \ $(top_srcdir)/m4/geany-revision.m4 \ $(top_srcdir)/m4/geany-socket.m4 \ $(top_srcdir)/m4/geany-status.m4 \ $(top_srcdir)/m4/geany-the-force.m4 \ $(top_srcdir)/m4/geany-utils.m4 $(top_srcdir)/m4/geany-vte.m4 \ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/iconv.m4 \ $(top_srcdir)/m4/intlmacosx.m4 $(top_srcdir)/m4/lib-ld.m4 \ $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \ $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am \ $(am__dist_pkglibexec_SCRIPTS_DIST) $(geany_include_HEADERS) \ $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(libdir)" \ "$(DESTDIR)$(pkglibexecdir)" "$(DESTDIR)$(geany_includedir)" PROGRAMS = $(bin_PROGRAMS) am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } LTLIBRARIES = $(lib_LTLIBRARIES) am__DEPENDENCIES_1 = libgeany_la_DEPENDENCIES = $(top_builddir)/scintilla/liblexilla.la \ $(top_builddir)/scintilla/libscintilla.la \ $(builddir)/tagmanager/libtagmanager.la $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) am__libgeany_la_SOURCES_DIST = about.c about.h app.h build.c build.h \ callbacks.c callbacks.h dialogs.c dialogs.h document.c \ document.h editor.c editor.h encodings.c encodings.h \ filetypes.c filetypes.h geanyentryaction.c geanyentryaction.h \ geanymenubuttonaction.c geanymenubuttonaction.h geanyobject.c \ geanyobject.h geanywraplabel.c geanywraplabel.h gtkcompat.h \ highlighting.c highlighting.h highlightingmappings.h \ keybindings.c keybindings.h keyfile.c keyfile.h log.c log.h \ libmain.c main.h geany.h msgwindow.c msgwindow.h navqueue.c \ navqueue.h notebook.c notebook.h plugins.c plugins.h \ pluginutils.c pluginutils.h prefs.c prefs.h printing.c \ printing.h project.c project.h sciwrappers.c sciwrappers.h \ search.c search.h socket.c socket.h spawn.c spawn.h stash.c \ stash.h support.h symbols.c symbols.h templates.c templates.h \ toolbar.c toolbar.h tools.c tools.h sidebar.c sidebar.h \ ui_utils.c ui_utils.h utils.c utils.h prefix.c prefix.h osx.c \ osx.h win32.c win32.h vte.c vte.h @ENABLE_BINRELOC_TRUE@am__objects_1 = libgeany_la-prefix.lo @ENABLE_MAC_INTEGRATION_TRUE@am__objects_2 = libgeany_la-osx.lo @MINGW_TRUE@am__objects_3 = libgeany_la-win32.lo @MINGW_FALSE@am__objects_4 = libgeany_la-vte.lo am_libgeany_la_OBJECTS = libgeany_la-about.lo libgeany_la-build.lo \ libgeany_la-callbacks.lo libgeany_la-dialogs.lo \ libgeany_la-document.lo libgeany_la-editor.lo \ libgeany_la-encodings.lo libgeany_la-filetypes.lo \ libgeany_la-geanyentryaction.lo \ libgeany_la-geanymenubuttonaction.lo \ libgeany_la-geanyobject.lo libgeany_la-geanywraplabel.lo \ libgeany_la-highlighting.lo libgeany_la-keybindings.lo \ libgeany_la-keyfile.lo libgeany_la-log.lo \ libgeany_la-libmain.lo libgeany_la-msgwindow.lo \ libgeany_la-navqueue.lo libgeany_la-notebook.lo \ libgeany_la-plugins.lo libgeany_la-pluginutils.lo \ libgeany_la-prefs.lo libgeany_la-printing.lo \ libgeany_la-project.lo libgeany_la-sciwrappers.lo \ libgeany_la-search.lo libgeany_la-socket.lo \ libgeany_la-spawn.lo libgeany_la-stash.lo \ libgeany_la-symbols.lo libgeany_la-templates.lo \ libgeany_la-toolbar.lo libgeany_la-tools.lo \ libgeany_la-sidebar.lo libgeany_la-ui_utils.lo \ libgeany_la-utils.lo $(am__objects_1) $(am__objects_2) \ $(am__objects_3) $(am__objects_4) libgeany_la_OBJECTS = $(am_libgeany_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = libgeany_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(libgeany_la_LDFLAGS) $(LDFLAGS) -o $@ am_geany_OBJECTS = main.$(OBJEXT) geany_OBJECTS = $(am_geany_OBJECTS) geany_DEPENDENCIES = libgeany.la $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__append_5) geany_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(geany_LDFLAGS) $(LDFLAGS) -o $@ am__dist_pkglibexec_SCRIPTS_DIST = geany-run-helper.bat SCRIPTS = $(dist_pkglibexec_SCRIPTS) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/dummy1.Plo ./$(DEPDIR)/dummy2.Po \ ./$(DEPDIR)/libgeany_la-about.Plo \ ./$(DEPDIR)/libgeany_la-build.Plo \ ./$(DEPDIR)/libgeany_la-callbacks.Plo \ ./$(DEPDIR)/libgeany_la-dialogs.Plo \ ./$(DEPDIR)/libgeany_la-document.Plo \ ./$(DEPDIR)/libgeany_la-editor.Plo \ ./$(DEPDIR)/libgeany_la-encodings.Plo \ ./$(DEPDIR)/libgeany_la-filetypes.Plo \ ./$(DEPDIR)/libgeany_la-geanyentryaction.Plo \ ./$(DEPDIR)/libgeany_la-geanymenubuttonaction.Plo \ ./$(DEPDIR)/libgeany_la-geanyobject.Plo \ ./$(DEPDIR)/libgeany_la-geanywraplabel.Plo \ ./$(DEPDIR)/libgeany_la-highlighting.Plo \ ./$(DEPDIR)/libgeany_la-keybindings.Plo \ ./$(DEPDIR)/libgeany_la-keyfile.Plo \ ./$(DEPDIR)/libgeany_la-libmain.Plo \ ./$(DEPDIR)/libgeany_la-log.Plo \ ./$(DEPDIR)/libgeany_la-msgwindow.Plo \ ./$(DEPDIR)/libgeany_la-navqueue.Plo \ ./$(DEPDIR)/libgeany_la-notebook.Plo \ ./$(DEPDIR)/libgeany_la-osx.Plo \ ./$(DEPDIR)/libgeany_la-plugins.Plo \ ./$(DEPDIR)/libgeany_la-pluginutils.Plo \ ./$(DEPDIR)/libgeany_la-prefix.Plo \ ./$(DEPDIR)/libgeany_la-prefs.Plo \ ./$(DEPDIR)/libgeany_la-printing.Plo \ ./$(DEPDIR)/libgeany_la-project.Plo \ ./$(DEPDIR)/libgeany_la-sciwrappers.Plo \ ./$(DEPDIR)/libgeany_la-search.Plo \ ./$(DEPDIR)/libgeany_la-sidebar.Plo \ ./$(DEPDIR)/libgeany_la-socket.Plo \ ./$(DEPDIR)/libgeany_la-spawn.Plo \ ./$(DEPDIR)/libgeany_la-stash.Plo \ ./$(DEPDIR)/libgeany_la-symbols.Plo \ ./$(DEPDIR)/libgeany_la-templates.Plo \ ./$(DEPDIR)/libgeany_la-toolbar.Plo \ ./$(DEPDIR)/libgeany_la-tools.Plo \ ./$(DEPDIR)/libgeany_la-ui_utils.Plo \ ./$(DEPDIR)/libgeany_la-utils.Plo \ ./$(DEPDIR)/libgeany_la-vte.Plo \ ./$(DEPDIR)/libgeany_la-win32.Plo ./$(DEPDIR)/main.Po am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CXXFLAGS) $(CXXFLAGS) AM_V_CXX = $(am__v_CXX_@AM_V@) am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) am__v_CXX_0 = @echo " CXX " $@; am__v_CXX_1 = CXXLD = $(CXX) CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; am__v_CXXLD_1 = SOURCES = $(libgeany_la_SOURCES) $(nodist_EXTRA_libgeany_la_SOURCES) \ $(geany_SOURCES) $(nodist_EXTRA_geany_SOURCES) DIST_SOURCES = $(am__libgeany_la_SOURCES_DIST) $(geany_SOURCES) RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac HEADERS = $(geany_include_HEADERS) RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir distdir-am am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` DIST_SUBDIRS = $(SUBDIRS) am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" pkgdatadir = @pkgdatadir@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DEPENDENCIES = @DEPENDENCIES@ DLLTOOL = @DLLTOOL@ DOXYGEN = @DOXYGEN@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GEANY_DATA_DIR = @GEANY_DATA_DIR@ GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ GMSGFMT = @GMSGFMT@ GMSGFMT_015 = @GMSGFMT_015@ GREP = @GREP@ GTK_CFLAGS = @GTK_CFLAGS@ GTK_LIBS = @GTK_LIBS@ GTK_VERSION = @GTK_VERSION@ HAVE_CXX17 = @HAVE_CXX17@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTLLIBS = @INTLLIBS@ INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBGEANY_CFLAGS = @LIBGEANY_CFLAGS@ LIBGEANY_EXPORT_CFLAGS = @LIBGEANY_EXPORT_CFLAGS@ LIBGEANY_LDFLAGS = @LIBGEANY_LDFLAGS@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBICONV = @LTLIBICONV@ LTLIBINTL = @LTLIBINTL@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAC_INTEGRATION_CFLAGS = @MAC_INTEGRATION_CFLAGS@ MAC_INTEGRATION_LIBS = @MAC_INTEGRATION_LIBS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POSUB = @POSUB@ PYTHON = @PYTHON@ PYTHON_COMMAND = @PYTHON_COMMAND@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RST2HTML = @RST2HTML@ RST2PDF = @RST2PDF@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SORT = @SORT@ STRIP = @STRIP@ UNIQ = @UNIQ@ USE_NLS = @USE_NLS@ VERSION = @VERSION@ XGETTEXT = @XGETTEXT@ XGETTEXT_015 = @XGETTEXT_015@ XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = tagmanager EXTRA_DIST = \ gb.c \ plugindata.h \ documentprivate.h \ encodingsprivate.h \ filetypesprivate.h \ keybindingsprivate.h \ pluginprivate.h \ projectprivate.h AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/scintilla/include \ -I$(top_srcdir)/scintilla/lexilla/include \ -I$(srcdir)/tagmanager -DGTK -DGEANY_PRIVATE \ -DG_LOG_DOMAIN=\""Geany"\" @GTK_CFLAGS@ \ $(MAC_INTEGRATION_CFLAGS) $(am__append_4) $(am__append_11) lib_LTLIBRARIES = libgeany.la geany_SOURCES = main.c geany_LDADD = libgeany.la $(GTK_LIBS) $(INTLLIBS) $(am__append_5) geany_LDFLAGS = $(am__append_1) $(am__append_9) geany_includedir = $(includedir)/geany geany_include_HEADERS = \ app.h \ build.h \ dialogs.h \ document.h \ editor.h \ encodings.h \ filetypes.h \ geany.h \ gtkcompat.h \ highlighting.h \ keybindings.h \ main.h \ msgwindow.h \ navqueue.h \ plugindata.h \ pluginutils.h \ prefs.h \ project.h \ sciwrappers.h \ search.h \ spawn.h \ stash.h \ support.h \ symbols.h \ templates.h \ toolbar.h \ ui_utils.h \ utils.h libgeany_la_SOURCES = about.c about.h app.h build.c build.h \ callbacks.c callbacks.h dialogs.c dialogs.h document.c \ document.h editor.c editor.h encodings.c encodings.h \ filetypes.c filetypes.h geanyentryaction.c geanyentryaction.h \ geanymenubuttonaction.c geanymenubuttonaction.h geanyobject.c \ geanyobject.h geanywraplabel.c geanywraplabel.h gtkcompat.h \ highlighting.c highlighting.h highlightingmappings.h \ keybindings.c keybindings.h keyfile.c keyfile.h log.c log.h \ libmain.c main.h geany.h msgwindow.c msgwindow.h navqueue.c \ navqueue.h notebook.c notebook.h plugins.c plugins.h \ pluginutils.c pluginutils.h prefs.c prefs.h printing.c \ printing.h project.c project.h sciwrappers.c sciwrappers.h \ search.c search.h socket.c socket.h spawn.c spawn.h stash.c \ stash.h support.h symbols.c symbols.h templates.c templates.h \ toolbar.c toolbar.h tools.c tools.h sidebar.c sidebar.h \ ui_utils.c ui_utils.h utils.c utils.h $(am__append_2) \ $(am__append_3) $(am__append_6) $(am__append_12) libgeany_la_CFLAGS = $(AM_CPPFLAGS) @LIBGEANY_CFLAGS@ libgeany_la_LDFLAGS = @LIBGEANY_LDFLAGS@ $(am__append_8) libgeany_la_LIBADD = $(top_builddir)/scintilla/liblexilla.la \ $(top_builddir)/scintilla/libscintilla.la \ $(builddir)/tagmanager/libtagmanager.la @GTK_LIBS@ \ $(MAC_INTEGRATION_LIBS) $(INTLLIBS) $(am__append_7) # tell automake we have a C++ file so it uses the C++ linker we need for Scintilla nodist_EXTRA_libgeany_la_SOURCES = dummy1.cxx nodist_EXTRA_geany_SOURCES = dummy2.cxx CLEANFILES = $(am__append_10) signallist.i @MINGW_TRUE@WINDRES = $(host_alias)-windres glade_file = $(top_srcdir)/data/geany.glade # install the run script @MINGW_TRUE@dist_pkglibexec_SCRIPTS = geany-run-helper.bat all: all-recursive .SUFFIXES: .SUFFIXES: .c .cxx .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu src/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ || test -f $$p1 \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list install-libLTLIBRARIES: $(lib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ } uninstall-libLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ done clean-libLTLIBRARIES: -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) @list='$(lib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libgeany.la: $(libgeany_la_OBJECTS) $(libgeany_la_DEPENDENCIES) $(EXTRA_libgeany_la_DEPENDENCIES) $(AM_V_CXXLD)$(libgeany_la_LINK) -rpath $(libdir) $(libgeany_la_OBJECTS) $(libgeany_la_LIBADD) $(LIBS) geany$(EXEEXT): $(geany_OBJECTS) $(geany_DEPENDENCIES) $(EXTRA_geany_DEPENDENCIES) @rm -f geany$(EXEEXT) $(AM_V_CXXLD)$(geany_LINK) $(geany_OBJECTS) $(geany_LDADD) $(LIBS) install-dist_pkglibexecSCRIPTS: $(dist_pkglibexec_SCRIPTS) @$(NORMAL_INSTALL) @list='$(dist_pkglibexec_SCRIPTS)'; test -n "$(pkglibexecdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(pkglibexecdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkglibexecdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n' \ -e 'h;s|.*|.|' \ -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) { files[d] = files[d] " " $$1; \ if (++n[d] == $(am__install_max)) { \ print "f", d, files[d]; n[d] = 0; files[d] = "" } } \ else { print "f", d "/" $$4, $$1 } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(pkglibexecdir)$$dir'"; \ $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(pkglibexecdir)$$dir" || exit $$?; \ } \ ; done uninstall-dist_pkglibexecSCRIPTS: @$(NORMAL_UNINSTALL) @list='$(dist_pkglibexec_SCRIPTS)'; test -n "$(pkglibexecdir)" || exit 0; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 's,.*/,,;$(transform)'`; \ dir='$(DESTDIR)$(pkglibexecdir)'; $(am__uninstall_files_from_dir) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dummy1.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dummy2.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgeany_la-about.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgeany_la-build.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgeany_la-callbacks.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgeany_la-dialogs.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgeany_la-document.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgeany_la-editor.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgeany_la-encodings.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgeany_la-filetypes.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgeany_la-geanyentryaction.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgeany_la-geanymenubuttonaction.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgeany_la-geanyobject.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgeany_la-geanywraplabel.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgeany_la-highlighting.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgeany_la-keybindings.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgeany_la-keyfile.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgeany_la-libmain.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgeany_la-log.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgeany_la-msgwindow.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgeany_la-navqueue.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgeany_la-notebook.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgeany_la-osx.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgeany_la-plugins.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgeany_la-pluginutils.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgeany_la-prefix.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgeany_la-prefs.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgeany_la-printing.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgeany_la-project.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgeany_la-sciwrappers.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgeany_la-search.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgeany_la-sidebar.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgeany_la-socket.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgeany_la-spawn.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgeany_la-stash.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgeany_la-symbols.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgeany_la-templates.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgeany_la-toolbar.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgeany_la-tools.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgeany_la-ui_utils.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgeany_la-utils.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgeany_la-vte.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgeany_la-win32.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< libgeany_la-about.lo: about.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -MT libgeany_la-about.lo -MD -MP -MF $(DEPDIR)/libgeany_la-about.Tpo -c -o libgeany_la-about.lo `test -f 'about.c' || echo '$(srcdir)/'`about.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgeany_la-about.Tpo $(DEPDIR)/libgeany_la-about.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='about.c' object='libgeany_la-about.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -c -o libgeany_la-about.lo `test -f 'about.c' || echo '$(srcdir)/'`about.c libgeany_la-build.lo: build.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -MT libgeany_la-build.lo -MD -MP -MF $(DEPDIR)/libgeany_la-build.Tpo -c -o libgeany_la-build.lo `test -f 'build.c' || echo '$(srcdir)/'`build.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgeany_la-build.Tpo $(DEPDIR)/libgeany_la-build.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='build.c' object='libgeany_la-build.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -c -o libgeany_la-build.lo `test -f 'build.c' || echo '$(srcdir)/'`build.c libgeany_la-callbacks.lo: callbacks.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -MT libgeany_la-callbacks.lo -MD -MP -MF $(DEPDIR)/libgeany_la-callbacks.Tpo -c -o libgeany_la-callbacks.lo `test -f 'callbacks.c' || echo '$(srcdir)/'`callbacks.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgeany_la-callbacks.Tpo $(DEPDIR)/libgeany_la-callbacks.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='callbacks.c' object='libgeany_la-callbacks.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -c -o libgeany_la-callbacks.lo `test -f 'callbacks.c' || echo '$(srcdir)/'`callbacks.c libgeany_la-dialogs.lo: dialogs.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -MT libgeany_la-dialogs.lo -MD -MP -MF $(DEPDIR)/libgeany_la-dialogs.Tpo -c -o libgeany_la-dialogs.lo `test -f 'dialogs.c' || echo '$(srcdir)/'`dialogs.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgeany_la-dialogs.Tpo $(DEPDIR)/libgeany_la-dialogs.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dialogs.c' object='libgeany_la-dialogs.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -c -o libgeany_la-dialogs.lo `test -f 'dialogs.c' || echo '$(srcdir)/'`dialogs.c libgeany_la-document.lo: document.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -MT libgeany_la-document.lo -MD -MP -MF $(DEPDIR)/libgeany_la-document.Tpo -c -o libgeany_la-document.lo `test -f 'document.c' || echo '$(srcdir)/'`document.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgeany_la-document.Tpo $(DEPDIR)/libgeany_la-document.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='document.c' object='libgeany_la-document.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -c -o libgeany_la-document.lo `test -f 'document.c' || echo '$(srcdir)/'`document.c libgeany_la-editor.lo: editor.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -MT libgeany_la-editor.lo -MD -MP -MF $(DEPDIR)/libgeany_la-editor.Tpo -c -o libgeany_la-editor.lo `test -f 'editor.c' || echo '$(srcdir)/'`editor.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgeany_la-editor.Tpo $(DEPDIR)/libgeany_la-editor.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='editor.c' object='libgeany_la-editor.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -c -o libgeany_la-editor.lo `test -f 'editor.c' || echo '$(srcdir)/'`editor.c libgeany_la-encodings.lo: encodings.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -MT libgeany_la-encodings.lo -MD -MP -MF $(DEPDIR)/libgeany_la-encodings.Tpo -c -o libgeany_la-encodings.lo `test -f 'encodings.c' || echo '$(srcdir)/'`encodings.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgeany_la-encodings.Tpo $(DEPDIR)/libgeany_la-encodings.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='encodings.c' object='libgeany_la-encodings.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -c -o libgeany_la-encodings.lo `test -f 'encodings.c' || echo '$(srcdir)/'`encodings.c libgeany_la-filetypes.lo: filetypes.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -MT libgeany_la-filetypes.lo -MD -MP -MF $(DEPDIR)/libgeany_la-filetypes.Tpo -c -o libgeany_la-filetypes.lo `test -f 'filetypes.c' || echo '$(srcdir)/'`filetypes.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgeany_la-filetypes.Tpo $(DEPDIR)/libgeany_la-filetypes.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filetypes.c' object='libgeany_la-filetypes.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -c -o libgeany_la-filetypes.lo `test -f 'filetypes.c' || echo '$(srcdir)/'`filetypes.c libgeany_la-geanyentryaction.lo: geanyentryaction.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -MT libgeany_la-geanyentryaction.lo -MD -MP -MF $(DEPDIR)/libgeany_la-geanyentryaction.Tpo -c -o libgeany_la-geanyentryaction.lo `test -f 'geanyentryaction.c' || echo '$(srcdir)/'`geanyentryaction.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgeany_la-geanyentryaction.Tpo $(DEPDIR)/libgeany_la-geanyentryaction.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='geanyentryaction.c' object='libgeany_la-geanyentryaction.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -c -o libgeany_la-geanyentryaction.lo `test -f 'geanyentryaction.c' || echo '$(srcdir)/'`geanyentryaction.c libgeany_la-geanymenubuttonaction.lo: geanymenubuttonaction.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -MT libgeany_la-geanymenubuttonaction.lo -MD -MP -MF $(DEPDIR)/libgeany_la-geanymenubuttonaction.Tpo -c -o libgeany_la-geanymenubuttonaction.lo `test -f 'geanymenubuttonaction.c' || echo '$(srcdir)/'`geanymenubuttonaction.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgeany_la-geanymenubuttonaction.Tpo $(DEPDIR)/libgeany_la-geanymenubuttonaction.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='geanymenubuttonaction.c' object='libgeany_la-geanymenubuttonaction.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -c -o libgeany_la-geanymenubuttonaction.lo `test -f 'geanymenubuttonaction.c' || echo '$(srcdir)/'`geanymenubuttonaction.c libgeany_la-geanyobject.lo: geanyobject.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -MT libgeany_la-geanyobject.lo -MD -MP -MF $(DEPDIR)/libgeany_la-geanyobject.Tpo -c -o libgeany_la-geanyobject.lo `test -f 'geanyobject.c' || echo '$(srcdir)/'`geanyobject.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgeany_la-geanyobject.Tpo $(DEPDIR)/libgeany_la-geanyobject.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='geanyobject.c' object='libgeany_la-geanyobject.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -c -o libgeany_la-geanyobject.lo `test -f 'geanyobject.c' || echo '$(srcdir)/'`geanyobject.c libgeany_la-geanywraplabel.lo: geanywraplabel.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -MT libgeany_la-geanywraplabel.lo -MD -MP -MF $(DEPDIR)/libgeany_la-geanywraplabel.Tpo -c -o libgeany_la-geanywraplabel.lo `test -f 'geanywraplabel.c' || echo '$(srcdir)/'`geanywraplabel.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgeany_la-geanywraplabel.Tpo $(DEPDIR)/libgeany_la-geanywraplabel.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='geanywraplabel.c' object='libgeany_la-geanywraplabel.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -c -o libgeany_la-geanywraplabel.lo `test -f 'geanywraplabel.c' || echo '$(srcdir)/'`geanywraplabel.c libgeany_la-highlighting.lo: highlighting.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -MT libgeany_la-highlighting.lo -MD -MP -MF $(DEPDIR)/libgeany_la-highlighting.Tpo -c -o libgeany_la-highlighting.lo `test -f 'highlighting.c' || echo '$(srcdir)/'`highlighting.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgeany_la-highlighting.Tpo $(DEPDIR)/libgeany_la-highlighting.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='highlighting.c' object='libgeany_la-highlighting.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -c -o libgeany_la-highlighting.lo `test -f 'highlighting.c' || echo '$(srcdir)/'`highlighting.c libgeany_la-keybindings.lo: keybindings.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -MT libgeany_la-keybindings.lo -MD -MP -MF $(DEPDIR)/libgeany_la-keybindings.Tpo -c -o libgeany_la-keybindings.lo `test -f 'keybindings.c' || echo '$(srcdir)/'`keybindings.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgeany_la-keybindings.Tpo $(DEPDIR)/libgeany_la-keybindings.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='keybindings.c' object='libgeany_la-keybindings.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -c -o libgeany_la-keybindings.lo `test -f 'keybindings.c' || echo '$(srcdir)/'`keybindings.c libgeany_la-keyfile.lo: keyfile.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -MT libgeany_la-keyfile.lo -MD -MP -MF $(DEPDIR)/libgeany_la-keyfile.Tpo -c -o libgeany_la-keyfile.lo `test -f 'keyfile.c' || echo '$(srcdir)/'`keyfile.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgeany_la-keyfile.Tpo $(DEPDIR)/libgeany_la-keyfile.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='keyfile.c' object='libgeany_la-keyfile.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -c -o libgeany_la-keyfile.lo `test -f 'keyfile.c' || echo '$(srcdir)/'`keyfile.c libgeany_la-log.lo: log.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -MT libgeany_la-log.lo -MD -MP -MF $(DEPDIR)/libgeany_la-log.Tpo -c -o libgeany_la-log.lo `test -f 'log.c' || echo '$(srcdir)/'`log.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgeany_la-log.Tpo $(DEPDIR)/libgeany_la-log.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='log.c' object='libgeany_la-log.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -c -o libgeany_la-log.lo `test -f 'log.c' || echo '$(srcdir)/'`log.c libgeany_la-libmain.lo: libmain.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -MT libgeany_la-libmain.lo -MD -MP -MF $(DEPDIR)/libgeany_la-libmain.Tpo -c -o libgeany_la-libmain.lo `test -f 'libmain.c' || echo '$(srcdir)/'`libmain.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgeany_la-libmain.Tpo $(DEPDIR)/libgeany_la-libmain.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libmain.c' object='libgeany_la-libmain.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -c -o libgeany_la-libmain.lo `test -f 'libmain.c' || echo '$(srcdir)/'`libmain.c libgeany_la-msgwindow.lo: msgwindow.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -MT libgeany_la-msgwindow.lo -MD -MP -MF $(DEPDIR)/libgeany_la-msgwindow.Tpo -c -o libgeany_la-msgwindow.lo `test -f 'msgwindow.c' || echo '$(srcdir)/'`msgwindow.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgeany_la-msgwindow.Tpo $(DEPDIR)/libgeany_la-msgwindow.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='msgwindow.c' object='libgeany_la-msgwindow.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -c -o libgeany_la-msgwindow.lo `test -f 'msgwindow.c' || echo '$(srcdir)/'`msgwindow.c libgeany_la-navqueue.lo: navqueue.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -MT libgeany_la-navqueue.lo -MD -MP -MF $(DEPDIR)/libgeany_la-navqueue.Tpo -c -o libgeany_la-navqueue.lo `test -f 'navqueue.c' || echo '$(srcdir)/'`navqueue.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgeany_la-navqueue.Tpo $(DEPDIR)/libgeany_la-navqueue.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='navqueue.c' object='libgeany_la-navqueue.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -c -o libgeany_la-navqueue.lo `test -f 'navqueue.c' || echo '$(srcdir)/'`navqueue.c libgeany_la-notebook.lo: notebook.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -MT libgeany_la-notebook.lo -MD -MP -MF $(DEPDIR)/libgeany_la-notebook.Tpo -c -o libgeany_la-notebook.lo `test -f 'notebook.c' || echo '$(srcdir)/'`notebook.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgeany_la-notebook.Tpo $(DEPDIR)/libgeany_la-notebook.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='notebook.c' object='libgeany_la-notebook.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -c -o libgeany_la-notebook.lo `test -f 'notebook.c' || echo '$(srcdir)/'`notebook.c libgeany_la-plugins.lo: plugins.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -MT libgeany_la-plugins.lo -MD -MP -MF $(DEPDIR)/libgeany_la-plugins.Tpo -c -o libgeany_la-plugins.lo `test -f 'plugins.c' || echo '$(srcdir)/'`plugins.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgeany_la-plugins.Tpo $(DEPDIR)/libgeany_la-plugins.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='plugins.c' object='libgeany_la-plugins.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -c -o libgeany_la-plugins.lo `test -f 'plugins.c' || echo '$(srcdir)/'`plugins.c libgeany_la-pluginutils.lo: pluginutils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -MT libgeany_la-pluginutils.lo -MD -MP -MF $(DEPDIR)/libgeany_la-pluginutils.Tpo -c -o libgeany_la-pluginutils.lo `test -f 'pluginutils.c' || echo '$(srcdir)/'`pluginutils.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgeany_la-pluginutils.Tpo $(DEPDIR)/libgeany_la-pluginutils.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pluginutils.c' object='libgeany_la-pluginutils.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -c -o libgeany_la-pluginutils.lo `test -f 'pluginutils.c' || echo '$(srcdir)/'`pluginutils.c libgeany_la-prefs.lo: prefs.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -MT libgeany_la-prefs.lo -MD -MP -MF $(DEPDIR)/libgeany_la-prefs.Tpo -c -o libgeany_la-prefs.lo `test -f 'prefs.c' || echo '$(srcdir)/'`prefs.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgeany_la-prefs.Tpo $(DEPDIR)/libgeany_la-prefs.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='prefs.c' object='libgeany_la-prefs.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -c -o libgeany_la-prefs.lo `test -f 'prefs.c' || echo '$(srcdir)/'`prefs.c libgeany_la-printing.lo: printing.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -MT libgeany_la-printing.lo -MD -MP -MF $(DEPDIR)/libgeany_la-printing.Tpo -c -o libgeany_la-printing.lo `test -f 'printing.c' || echo '$(srcdir)/'`printing.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgeany_la-printing.Tpo $(DEPDIR)/libgeany_la-printing.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='printing.c' object='libgeany_la-printing.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -c -o libgeany_la-printing.lo `test -f 'printing.c' || echo '$(srcdir)/'`printing.c libgeany_la-project.lo: project.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -MT libgeany_la-project.lo -MD -MP -MF $(DEPDIR)/libgeany_la-project.Tpo -c -o libgeany_la-project.lo `test -f 'project.c' || echo '$(srcdir)/'`project.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgeany_la-project.Tpo $(DEPDIR)/libgeany_la-project.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='project.c' object='libgeany_la-project.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -c -o libgeany_la-project.lo `test -f 'project.c' || echo '$(srcdir)/'`project.c libgeany_la-sciwrappers.lo: sciwrappers.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -MT libgeany_la-sciwrappers.lo -MD -MP -MF $(DEPDIR)/libgeany_la-sciwrappers.Tpo -c -o libgeany_la-sciwrappers.lo `test -f 'sciwrappers.c' || echo '$(srcdir)/'`sciwrappers.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgeany_la-sciwrappers.Tpo $(DEPDIR)/libgeany_la-sciwrappers.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sciwrappers.c' object='libgeany_la-sciwrappers.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -c -o libgeany_la-sciwrappers.lo `test -f 'sciwrappers.c' || echo '$(srcdir)/'`sciwrappers.c libgeany_la-search.lo: search.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -MT libgeany_la-search.lo -MD -MP -MF $(DEPDIR)/libgeany_la-search.Tpo -c -o libgeany_la-search.lo `test -f 'search.c' || echo '$(srcdir)/'`search.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgeany_la-search.Tpo $(DEPDIR)/libgeany_la-search.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='search.c' object='libgeany_la-search.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -c -o libgeany_la-search.lo `test -f 'search.c' || echo '$(srcdir)/'`search.c libgeany_la-socket.lo: socket.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -MT libgeany_la-socket.lo -MD -MP -MF $(DEPDIR)/libgeany_la-socket.Tpo -c -o libgeany_la-socket.lo `test -f 'socket.c' || echo '$(srcdir)/'`socket.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgeany_la-socket.Tpo $(DEPDIR)/libgeany_la-socket.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='socket.c' object='libgeany_la-socket.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -c -o libgeany_la-socket.lo `test -f 'socket.c' || echo '$(srcdir)/'`socket.c libgeany_la-spawn.lo: spawn.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -MT libgeany_la-spawn.lo -MD -MP -MF $(DEPDIR)/libgeany_la-spawn.Tpo -c -o libgeany_la-spawn.lo `test -f 'spawn.c' || echo '$(srcdir)/'`spawn.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgeany_la-spawn.Tpo $(DEPDIR)/libgeany_la-spawn.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='spawn.c' object='libgeany_la-spawn.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -c -o libgeany_la-spawn.lo `test -f 'spawn.c' || echo '$(srcdir)/'`spawn.c libgeany_la-stash.lo: stash.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -MT libgeany_la-stash.lo -MD -MP -MF $(DEPDIR)/libgeany_la-stash.Tpo -c -o libgeany_la-stash.lo `test -f 'stash.c' || echo '$(srcdir)/'`stash.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgeany_la-stash.Tpo $(DEPDIR)/libgeany_la-stash.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='stash.c' object='libgeany_la-stash.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -c -o libgeany_la-stash.lo `test -f 'stash.c' || echo '$(srcdir)/'`stash.c libgeany_la-symbols.lo: symbols.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -MT libgeany_la-symbols.lo -MD -MP -MF $(DEPDIR)/libgeany_la-symbols.Tpo -c -o libgeany_la-symbols.lo `test -f 'symbols.c' || echo '$(srcdir)/'`symbols.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgeany_la-symbols.Tpo $(DEPDIR)/libgeany_la-symbols.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='symbols.c' object='libgeany_la-symbols.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -c -o libgeany_la-symbols.lo `test -f 'symbols.c' || echo '$(srcdir)/'`symbols.c libgeany_la-templates.lo: templates.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -MT libgeany_la-templates.lo -MD -MP -MF $(DEPDIR)/libgeany_la-templates.Tpo -c -o libgeany_la-templates.lo `test -f 'templates.c' || echo '$(srcdir)/'`templates.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgeany_la-templates.Tpo $(DEPDIR)/libgeany_la-templates.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='templates.c' object='libgeany_la-templates.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -c -o libgeany_la-templates.lo `test -f 'templates.c' || echo '$(srcdir)/'`templates.c libgeany_la-toolbar.lo: toolbar.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -MT libgeany_la-toolbar.lo -MD -MP -MF $(DEPDIR)/libgeany_la-toolbar.Tpo -c -o libgeany_la-toolbar.lo `test -f 'toolbar.c' || echo '$(srcdir)/'`toolbar.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgeany_la-toolbar.Tpo $(DEPDIR)/libgeany_la-toolbar.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='toolbar.c' object='libgeany_la-toolbar.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -c -o libgeany_la-toolbar.lo `test -f 'toolbar.c' || echo '$(srcdir)/'`toolbar.c libgeany_la-tools.lo: tools.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -MT libgeany_la-tools.lo -MD -MP -MF $(DEPDIR)/libgeany_la-tools.Tpo -c -o libgeany_la-tools.lo `test -f 'tools.c' || echo '$(srcdir)/'`tools.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgeany_la-tools.Tpo $(DEPDIR)/libgeany_la-tools.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tools.c' object='libgeany_la-tools.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -c -o libgeany_la-tools.lo `test -f 'tools.c' || echo '$(srcdir)/'`tools.c libgeany_la-sidebar.lo: sidebar.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -MT libgeany_la-sidebar.lo -MD -MP -MF $(DEPDIR)/libgeany_la-sidebar.Tpo -c -o libgeany_la-sidebar.lo `test -f 'sidebar.c' || echo '$(srcdir)/'`sidebar.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgeany_la-sidebar.Tpo $(DEPDIR)/libgeany_la-sidebar.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sidebar.c' object='libgeany_la-sidebar.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -c -o libgeany_la-sidebar.lo `test -f 'sidebar.c' || echo '$(srcdir)/'`sidebar.c libgeany_la-ui_utils.lo: ui_utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -MT libgeany_la-ui_utils.lo -MD -MP -MF $(DEPDIR)/libgeany_la-ui_utils.Tpo -c -o libgeany_la-ui_utils.lo `test -f 'ui_utils.c' || echo '$(srcdir)/'`ui_utils.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgeany_la-ui_utils.Tpo $(DEPDIR)/libgeany_la-ui_utils.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ui_utils.c' object='libgeany_la-ui_utils.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -c -o libgeany_la-ui_utils.lo `test -f 'ui_utils.c' || echo '$(srcdir)/'`ui_utils.c libgeany_la-utils.lo: utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -MT libgeany_la-utils.lo -MD -MP -MF $(DEPDIR)/libgeany_la-utils.Tpo -c -o libgeany_la-utils.lo `test -f 'utils.c' || echo '$(srcdir)/'`utils.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgeany_la-utils.Tpo $(DEPDIR)/libgeany_la-utils.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='utils.c' object='libgeany_la-utils.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -c -o libgeany_la-utils.lo `test -f 'utils.c' || echo '$(srcdir)/'`utils.c libgeany_la-prefix.lo: prefix.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -MT libgeany_la-prefix.lo -MD -MP -MF $(DEPDIR)/libgeany_la-prefix.Tpo -c -o libgeany_la-prefix.lo `test -f 'prefix.c' || echo '$(srcdir)/'`prefix.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgeany_la-prefix.Tpo $(DEPDIR)/libgeany_la-prefix.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='prefix.c' object='libgeany_la-prefix.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -c -o libgeany_la-prefix.lo `test -f 'prefix.c' || echo '$(srcdir)/'`prefix.c libgeany_la-osx.lo: osx.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -MT libgeany_la-osx.lo -MD -MP -MF $(DEPDIR)/libgeany_la-osx.Tpo -c -o libgeany_la-osx.lo `test -f 'osx.c' || echo '$(srcdir)/'`osx.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgeany_la-osx.Tpo $(DEPDIR)/libgeany_la-osx.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='osx.c' object='libgeany_la-osx.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -c -o libgeany_la-osx.lo `test -f 'osx.c' || echo '$(srcdir)/'`osx.c libgeany_la-win32.lo: win32.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -MT libgeany_la-win32.lo -MD -MP -MF $(DEPDIR)/libgeany_la-win32.Tpo -c -o libgeany_la-win32.lo `test -f 'win32.c' || echo '$(srcdir)/'`win32.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgeany_la-win32.Tpo $(DEPDIR)/libgeany_la-win32.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='win32.c' object='libgeany_la-win32.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -c -o libgeany_la-win32.lo `test -f 'win32.c' || echo '$(srcdir)/'`win32.c libgeany_la-vte.lo: vte.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -MT libgeany_la-vte.lo -MD -MP -MF $(DEPDIR)/libgeany_la-vte.Tpo -c -o libgeany_la-vte.lo `test -f 'vte.c' || echo '$(srcdir)/'`vte.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgeany_la-vte.Tpo $(DEPDIR)/libgeany_la-vte.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vte.c' object='libgeany_la-vte.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgeany_la_CFLAGS) $(CFLAGS) -c -o libgeany_la-vte.lo `test -f 'vte.c' || echo '$(srcdir)/'`vte.c .cxx.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cxx.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cxx.lo: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-geany_includeHEADERS: $(geany_include_HEADERS) @$(NORMAL_INSTALL) @list='$(geany_include_HEADERS)'; test -n "$(geany_includedir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(geany_includedir)'"; \ $(MKDIR_P) "$(DESTDIR)$(geany_includedir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(geany_includedir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(geany_includedir)" || exit $$?; \ done uninstall-geany_includeHEADERS: @$(NORMAL_UNINSTALL) @list='$(geany_include_HEADERS)'; test -n "$(geany_includedir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(geany_includedir)'; $(am__uninstall_files_from_dir) # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile $(PROGRAMS) $(LTLIBRARIES) $(SCRIPTS) $(HEADERS) install-binPROGRAMS: install-libLTLIBRARIES installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pkglibexecdir)" "$(DESTDIR)$(geany_includedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-binPROGRAMS clean-generic clean-libLTLIBRARIES \ clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f ./$(DEPDIR)/dummy1.Plo -rm -f ./$(DEPDIR)/dummy2.Po -rm -f ./$(DEPDIR)/libgeany_la-about.Plo -rm -f ./$(DEPDIR)/libgeany_la-build.Plo -rm -f ./$(DEPDIR)/libgeany_la-callbacks.Plo -rm -f ./$(DEPDIR)/libgeany_la-dialogs.Plo -rm -f ./$(DEPDIR)/libgeany_la-document.Plo -rm -f ./$(DEPDIR)/libgeany_la-editor.Plo -rm -f ./$(DEPDIR)/libgeany_la-encodings.Plo -rm -f ./$(DEPDIR)/libgeany_la-filetypes.Plo -rm -f ./$(DEPDIR)/libgeany_la-geanyentryaction.Plo -rm -f ./$(DEPDIR)/libgeany_la-geanymenubuttonaction.Plo -rm -f ./$(DEPDIR)/libgeany_la-geanyobject.Plo -rm -f ./$(DEPDIR)/libgeany_la-geanywraplabel.Plo -rm -f ./$(DEPDIR)/libgeany_la-highlighting.Plo -rm -f ./$(DEPDIR)/libgeany_la-keybindings.Plo -rm -f ./$(DEPDIR)/libgeany_la-keyfile.Plo -rm -f ./$(DEPDIR)/libgeany_la-libmain.Plo -rm -f ./$(DEPDIR)/libgeany_la-log.Plo -rm -f ./$(DEPDIR)/libgeany_la-msgwindow.Plo -rm -f ./$(DEPDIR)/libgeany_la-navqueue.Plo -rm -f ./$(DEPDIR)/libgeany_la-notebook.Plo -rm -f ./$(DEPDIR)/libgeany_la-osx.Plo -rm -f ./$(DEPDIR)/libgeany_la-plugins.Plo -rm -f ./$(DEPDIR)/libgeany_la-pluginutils.Plo -rm -f ./$(DEPDIR)/libgeany_la-prefix.Plo -rm -f ./$(DEPDIR)/libgeany_la-prefs.Plo -rm -f ./$(DEPDIR)/libgeany_la-printing.Plo -rm -f ./$(DEPDIR)/libgeany_la-project.Plo -rm -f ./$(DEPDIR)/libgeany_la-sciwrappers.Plo -rm -f ./$(DEPDIR)/libgeany_la-search.Plo -rm -f ./$(DEPDIR)/libgeany_la-sidebar.Plo -rm -f ./$(DEPDIR)/libgeany_la-socket.Plo -rm -f ./$(DEPDIR)/libgeany_la-spawn.Plo -rm -f ./$(DEPDIR)/libgeany_la-stash.Plo -rm -f ./$(DEPDIR)/libgeany_la-symbols.Plo -rm -f ./$(DEPDIR)/libgeany_la-templates.Plo -rm -f ./$(DEPDIR)/libgeany_la-toolbar.Plo -rm -f ./$(DEPDIR)/libgeany_la-tools.Plo -rm -f ./$(DEPDIR)/libgeany_la-ui_utils.Plo -rm -f ./$(DEPDIR)/libgeany_la-utils.Plo -rm -f ./$(DEPDIR)/libgeany_la-vte.Plo -rm -f ./$(DEPDIR)/libgeany_la-win32.Plo -rm -f ./$(DEPDIR)/main.Po -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-geany_includeHEADERS install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-binPROGRAMS install-dist_pkglibexecSCRIPTS \ install-libLTLIBRARIES @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) install-exec-hook install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f ./$(DEPDIR)/dummy1.Plo -rm -f ./$(DEPDIR)/dummy2.Po -rm -f ./$(DEPDIR)/libgeany_la-about.Plo -rm -f ./$(DEPDIR)/libgeany_la-build.Plo -rm -f ./$(DEPDIR)/libgeany_la-callbacks.Plo -rm -f ./$(DEPDIR)/libgeany_la-dialogs.Plo -rm -f ./$(DEPDIR)/libgeany_la-document.Plo -rm -f ./$(DEPDIR)/libgeany_la-editor.Plo -rm -f ./$(DEPDIR)/libgeany_la-encodings.Plo -rm -f ./$(DEPDIR)/libgeany_la-filetypes.Plo -rm -f ./$(DEPDIR)/libgeany_la-geanyentryaction.Plo -rm -f ./$(DEPDIR)/libgeany_la-geanymenubuttonaction.Plo -rm -f ./$(DEPDIR)/libgeany_la-geanyobject.Plo -rm -f ./$(DEPDIR)/libgeany_la-geanywraplabel.Plo -rm -f ./$(DEPDIR)/libgeany_la-highlighting.Plo -rm -f ./$(DEPDIR)/libgeany_la-keybindings.Plo -rm -f ./$(DEPDIR)/libgeany_la-keyfile.Plo -rm -f ./$(DEPDIR)/libgeany_la-libmain.Plo -rm -f ./$(DEPDIR)/libgeany_la-log.Plo -rm -f ./$(DEPDIR)/libgeany_la-msgwindow.Plo -rm -f ./$(DEPDIR)/libgeany_la-navqueue.Plo -rm -f ./$(DEPDIR)/libgeany_la-notebook.Plo -rm -f ./$(DEPDIR)/libgeany_la-osx.Plo -rm -f ./$(DEPDIR)/libgeany_la-plugins.Plo -rm -f ./$(DEPDIR)/libgeany_la-pluginutils.Plo -rm -f ./$(DEPDIR)/libgeany_la-prefix.Plo -rm -f ./$(DEPDIR)/libgeany_la-prefs.Plo -rm -f ./$(DEPDIR)/libgeany_la-printing.Plo -rm -f ./$(DEPDIR)/libgeany_la-project.Plo -rm -f ./$(DEPDIR)/libgeany_la-sciwrappers.Plo -rm -f ./$(DEPDIR)/libgeany_la-search.Plo -rm -f ./$(DEPDIR)/libgeany_la-sidebar.Plo -rm -f ./$(DEPDIR)/libgeany_la-socket.Plo -rm -f ./$(DEPDIR)/libgeany_la-spawn.Plo -rm -f ./$(DEPDIR)/libgeany_la-stash.Plo -rm -f ./$(DEPDIR)/libgeany_la-symbols.Plo -rm -f ./$(DEPDIR)/libgeany_la-templates.Plo -rm -f ./$(DEPDIR)/libgeany_la-toolbar.Plo -rm -f ./$(DEPDIR)/libgeany_la-tools.Plo -rm -f ./$(DEPDIR)/libgeany_la-ui_utils.Plo -rm -f ./$(DEPDIR)/libgeany_la-utils.Plo -rm -f ./$(DEPDIR)/libgeany_la-vte.Plo -rm -f ./$(DEPDIR)/libgeany_la-win32.Plo -rm -f ./$(DEPDIR)/main.Po -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-binPROGRAMS uninstall-dist_pkglibexecSCRIPTS \ uninstall-geany_includeHEADERS uninstall-libLTLIBRARIES .MAKE: $(am__recursive_targets) install-am install-exec-am \ install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ am--depfiles check check-am clean clean-binPROGRAMS \ clean-generic clean-libLTLIBRARIES clean-libtool cscopelist-am \ ctags ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-binPROGRAMS \ install-data install-data-am install-dist_pkglibexecSCRIPTS \ install-dvi install-dvi-am install-exec install-exec-am \ install-exec-hook install-geany_includeHEADERS install-html \ install-html-am install-info install-info-am \ install-libLTLIBRARIES install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am uninstall-binPROGRAMS \ uninstall-dist_pkglibexecSCRIPTS \ uninstall-geany_includeHEADERS uninstall-libLTLIBRARIES .PRECIOUS: Makefile @MINGW_TRUE@geany_private.res: $(top_srcdir)/geany_private.rc @MINGW_TRUE@ $(WINDRES) -i $(top_srcdir)/geany_private.rc --input-format=rc -o $@ -O coff callbacks.c: signallist.i signallist.i: $(glade_file) Makefile $(AM_V_GEN)$(top_srcdir)/scripts/gen-signallist.sh $(glade_file) $@ # Ubuntu ld has a bug so that libtool sees /usr/local/lib as a system path so # doesn't add RPATH, but ld requires explicit ldconfig there, unlike when # installing in /usr/lib. So, workaround this by calling it explicitly when # installing in /usr/local/lib and libgeany is not found by the linker. fix-ubuntu-libdir: if test "$(DESTDIR)$(libdir)" = /usr/local/lib && \ LANG=C ldd "$(DESTDIR)$(bindir)/geany" | grep -q 'libgeany.*not found' \ ; then \ ldconfig "$(DESTDIR)$(libdir)"; \ fi install-exec-hook: fix-ubuntu-libdir # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: geany-2.0/src/geanymenubuttonaction.h0000644000175000017500000000462614514252267015001 00000000000000/* * geanymenubuttonaction.h - this file is part of Geany, a fast and lightweight IDE * * Copyright 2009 The Geany contributors * * This program 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; either version 2 of the License, or * (at your option) any later version. * * This program 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef GEANY_MENU_BUTTON_ACTION_H #define GEANY_MENU_BUTTON_ACTION_H 1 #include "gtkcompat.h" G_BEGIN_DECLS #define GEANY_MENU_BUTTON_ACTION_TYPE (geany_menu_button_action_get_type()) #define GEANY_MENU_BUTTON_ACTION(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),\ GEANY_MENU_BUTTON_ACTION_TYPE, GeanyMenubuttonAction)) #define GEANY_MENU_BUTTON_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),\ GEANY_MENU_BUTTON_ACTION_TYPE, GeanyMenubuttonActionClass)) #define IS_GEANY_MENU_BUTTON_ACTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),\ GEANY_MENU_BUTTON_ACTION_TYPE)) #define IS_GEANY_MENU_BUTTON_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),\ GEANY_MENU_BUTTON_ACTION_TYPE)) typedef struct _GeanyMenubuttonAction GeanyMenubuttonAction; typedef struct _GeanyMenubuttonActionClass GeanyMenubuttonActionClass; struct _GeanyMenubuttonActionPrivate; struct _GeanyMenubuttonAction { GtkAction parent; struct _GeanyMenubuttonActionPrivate *priv; }; struct _GeanyMenubuttonActionClass { GtkActionClass parent_class; }; GType geany_menu_button_action_get_type (void); GtkAction* geany_menu_button_action_new (const gchar *name, const gchar *label, const gchar *tooltip, const gchar *tooltip_arrow, const gchar *stock_id); GtkWidget* geany_menu_button_action_get_menu (GeanyMenubuttonAction *action); void geany_menu_button_action_set_menu (GeanyMenubuttonAction *action, GtkWidget *menu); G_END_DECLS #endif /* GEANY_MENU_BUTTON_ACTION_H */ geany-2.0/src/utils.c0000644000175000017500000017663414514252267011523 00000000000000/* * utils.c - this file is part of Geany, a fast and lightweight IDE * * Copyright 2005 The Geany contributors * * This program 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; either version 2 of the License, or * (at your option) any later version. * * This program 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /* * General utility functions, non-GTK related. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include "utils.h" #include "app.h" #include "dialogs.h" #include "document.h" #include "prefs.h" #include "prefix.h" #include "sciwrappers.h" #include "spawn.h" #include "support.h" #include "tm_source_file.h" // for tm_get_real_path() #include "templates.h" #include "ui_utils.h" #include "win32.h" #include "osx.h" #include #include #include #include #include #include #include #ifdef HAVE_SYS_STAT_H # include #endif #ifdef HAVE_SYS_TYPES_H # include #endif #include #include /** * Tries to open the given URI in a browser. * On Windows, the system's default browser is opened. * On non-Windows systems, the browser command can be set in the preferences dialog. * If unset (empty) the system's default browser is used. If set it specifies the * command to execute. Either way, if it fails the user is prompted to correct the * pref. * * @param uri The URI to open in the web browser. * * @since 0.16 **/ GEANY_API_SYMBOL void utils_open_browser(const gchar *uri) { #ifdef G_OS_WIN32 g_return_if_fail(uri != NULL); win32_open_browser(uri); #else gchar *new_cmd, *argv[2] = { (gchar *) uri, NULL }; g_return_if_fail(uri != NULL); while (1) { /* Uses the user's default browser akin to xdg-open (in flatpak through a portal) */ if (EMPTY(tool_prefs.browser_cmd)) { if (gtk_show_uri_on_window(GTK_WINDOW(main_widgets.window), uri, GDK_CURRENT_TIME, NULL)) break; } else if (spawn_async(NULL, tool_prefs.browser_cmd, argv, NULL, NULL, NULL)) break; /* Allow the user to correct the pref. new_cmd may become empty. */ new_cmd = dialogs_show_input(_("Select Browser"), GTK_WINDOW(main_widgets.window), _("Failed to spawn the configured browser command. Please " "enter a valid command or leave it empty in order " "to spawn the system default browser."), tool_prefs.browser_cmd); if (new_cmd == NULL) /* user canceled */ break; SETPTR(tool_prefs.browser_cmd, new_cmd); } #endif } /* taken from anjuta, to determine the EOL mode of the file */ gint utils_get_line_endings(const gchar* buffer, gsize size) { gsize i; guint cr, lf, crlf, max_mode; gint mode; cr = lf = crlf = 0; for (i = 0; i < size ; i++) { if (buffer[i] == 0x0a) { /* LF */ lf++; } else if (buffer[i] == 0x0d) { if (i >= (size - 1)) { /* Last char, CR */ cr++; } else { if (buffer[i + 1] != 0x0a) { /* CR */ cr++; } else { /* CRLF */ crlf++; } i++; } } } /* Vote for the maximum */ mode = SC_EOL_LF; max_mode = lf; if (crlf > max_mode) { mode = SC_EOL_CRLF; max_mode = crlf; } if (cr > max_mode) { mode = SC_EOL_CR; max_mode = cr; } return mode; } gboolean utils_isbrace(gchar c, gboolean include_angles) { switch (c) { case '<': case '>': return include_angles; case '(': case ')': case '{': case '}': case '[': case ']': return TRUE; default: return FALSE; } } gboolean utils_is_opening_brace(gchar c, gboolean include_angles) { switch (c) { case '<': return include_angles; case '(': case '{': case '[': return TRUE; default: return FALSE; } } /** * Writes @a text into a file named @a filename. * If the file doesn't exist, it will be created. * If it already exists, it will be overwritten. * * @warning You should use @c g_file_set_contents() instead if you don't need * file permissions and other metadata to be preserved, as that always handles * disk exhaustion safely. * * @param filename The filename of the file to write, in locale encoding. * @param text The text to write into the file. * * @return 0 if the file was successfully written, otherwise the @c errno of the * failed operation is returned. **/ GEANY_API_SYMBOL gint utils_write_file(const gchar *filename, const gchar *text) { g_return_val_if_fail(filename != NULL, ENOENT); g_return_val_if_fail(text != NULL, EINVAL); if (file_prefs.use_safe_file_saving) { GError *error = NULL; if (! g_file_set_contents(filename, text, -1, &error)) { geany_debug("%s: could not write to file %s (%s)", G_STRFUNC, filename, error->message); g_error_free(error); return EIO; } } else { FILE *fp; gsize bytes_written, len; gboolean fail = FALSE; if (filename == NULL) return ENOENT; len = strlen(text); errno = 0; fp = g_fopen(filename, "w"); if (fp == NULL) fail = TRUE; else { bytes_written = fwrite(text, sizeof(gchar), len, fp); if (len != bytes_written) { fail = TRUE; geany_debug( "utils_write_file(): written only %"G_GSIZE_FORMAT" bytes, had to write %"G_GSIZE_FORMAT" bytes to %s", bytes_written, len, filename); } if (fclose(fp) != 0) fail = TRUE; } if (fail) { geany_debug("utils_write_file(): could not write to file %s (%s)", filename, g_strerror(errno)); return FALLBACK(errno, EIO); } } return 0; } /** Searches backward through @a size bytes looking for a '<'. * @param sel . * @param size . * @return @nullable The tag name (newly allocated) or @c NULL if no opening tag was found. */ GEANY_API_SYMBOL gchar *utils_find_open_xml_tag(const gchar sel[], gint size) { const gchar *cur, *begin; gsize len; cur = utils_find_open_xml_tag_pos(sel, size); if (cur == NULL) return NULL; cur++; /* skip the bracket */ begin = cur; while (strchr(":_-.", *cur) || isalnum(*cur)) cur++; len = (gsize)(cur - begin); return len ? g_strndup(begin, len) : NULL; } /** Searches backward through @a size bytes looking for a '<'. * @param sel . * @param size . * @return @nullable pointer to '<' of the found opening tag within @a sel, or @c NULL if no opening tag was found. */ GEANY_API_SYMBOL const gchar *utils_find_open_xml_tag_pos(const gchar sel[], gint size) { /* stolen from anjuta and modified */ const gchar *begin, *cur; if (G_UNLIKELY(size < 3)) { /* Smallest tag is "

" which is 3 characters */ return NULL; } begin = &sel[0]; cur = &sel[size - 1]; /* Skip to the character before the closing brace */ while (cur > begin) { if (*cur == '>') break; --cur; } --cur; /* skip whitespace */ while (cur > begin && isspace(*cur)) cur--; if (*cur == '/') return NULL; /* we found a short tag which doesn't need to be closed */ while (cur > begin) { if (*cur == '<') break; /* exit immediately if such non-valid XML/HTML is detected, e.g. " // leaves PHP mode function bug4() {} ?> // left function bug6() {} // leave function bug7() {} function h() {} ?> function bug8() {} function bug9() {} // this won't enter PHP, no spaces are allowed between the "<" and "script" < script language = php > function bug10() {} // does nothing, just resets mode for some tools not aware of the "script" thing ?>

geany-2.0/tests/ctags/cython_sample.pyx0000644000175000017500000000174014514252267015263 00000000000000# -*- cython-mode -*- # test code for python/cython functionality python_var = 1 cdef int i = 2 # cython identifiers are not indexed cdef : int j = 3 cdef k = 4 # no type here cdef int int_identity(int i) : return i # here is a long one cdef object int2string(int i) : return str(i) # a cdef class cdef class CDefClass : def __init__(self) : pass def standard_method(self,i) : return i cdef int c_method(self,int i) : return i # a python function def identity(x) : return x # a python class class StdClass : def return_me(self) : return "me" cdef CDefClass cdefObj = CDefClass() stdObj = StdClass() print "cython_sample: testing to make sure this file compiles and runs..." print "i is: ", i print "j is: ", j print "i via identity: ", int_identity(i) print "i via int2string: ", int2string(i) print "cdefObj: ", cdefObj.c_method(i) print "k via py identity", identity(k) print "py method call:", stdObj.return_me() geany-2.0/tests/ctags/structure.f.tags0000644000175000017500000000213214514252267015014 00000000000000aÌ64Îanon_type_1Ö0 member: anon_type_1 :: a anon_type_1Ì1ÎnestedÖ1 class: nested :: anon_type_1 flags: 1 cloudsÌ64ÎweatherÖ0 member: weather :: clouds dayÌ64ÎweatherÖ0 member: weather :: day initialized_structureÌ2048Ö0 struct: initialized_structure latestÌ16384Îinitialized_structureÖ0 variable: initialized_structure :: latest latestÌ16384Îuninitialized_structureÖ0 variable: uninitialized_structure :: latest level2Ì64ÎtopÖ0 member: top :: level2 level3aÌ64ÎnestedÖ0 member: nested :: level3a level3bÌ64ÎnestedÖ0 member: nested :: level3b monthÌ64ÎweatherÖ0 member: weather :: month nestedÌ1ÎtopÖ0 class: top :: nested nested_structureÌ2048Ö0 struct: nested_structure rainfallÌ64ÎweatherÖ0 member: weather :: rainfall topÌ1Înested_structureÖ0 class: nested_structure :: top uninitialized_structureÌ2048Ö0 struct: uninitialized_structure weatherÌ1Îinitialized_structureÖ0 class: initialized_structure :: weather weatherÌ1Îuninitialized_structureÖ0 class: uninitialized_structure :: weather yearÌ64ÎweatherÖ0 member: weather :: year geany-2.0/tests/ctags/intro.tex0000644000175000017500000000320714514252267013531 00000000000000% http://sip.clarku.edu/tutorials/TeX/intro.html \documentclass[12pt]{article} \usepackage{amsmath} % need for subequations \chapter{chapter text} \include{chapter1-intro.inc} \section{section1 text} It is desirable to print program code exactly as it is typed in a monospaced font. Use \verb \begin{verbatim} and \section{Introduction} \part{Part1} It is desirable to print program code exactly as it is typed in a monospaced font. Use \verb \begin{verbatim} and \subsection{subsection2} It is desirable to print program code exactly as it is typed in a monospaced font. Use \verb \begin{verbatim} and \subsubsection{subsubsection3 with extra text} It is desirable to print program code exactly as it is typed in a monospaced font. Use \verb \begin{verbatim} and \section[short section4]{section4 text} \paragraph[short para1]{long paragraph1} \paragraph{long paragraph2} It is desirable to print program code exactly as it is typed in a monospaced font. Use \verb \begin{verbatim} and \part{Part2} \section[shorter intro2]*{Introduction2longtitle} It is desirable to print program code exactly as it is typed in a monospaced font. Use \verb \begin{verbatim} and \subsection[subsec5 text]*{subsection5} \subparagraph[short subpara1]{long subparagraph1} \subparagraph{long subparagraph2} It is desirable to print program code exactly as it is typed in a monospaced font. Use \verb \begin{verbatim} and \subsubsection{subsubsection6 with extra text} It is desirable to print program code exactly as it is typed in a monospaced font. Use \verb \begin{verbatim} and \chapter{chapter2} \include{chapter2-intro.inc} \end{document} geany-2.0/tests/ctags/bug1799343-2.cpp0000644000175000017500000000045014514252267014055 00000000000000class P { protected: int x; }; namespace A { class P { protected: int x; }; class Q { int y; }; namespace C { class R: ::P, A::Q { int z; int f (int v) { return v + x; } }; } } namespace B { class S : A::C::R { int t; }; } geany-2.0/tests/ctags/simple.bat.tags0000644000175000017500000000023214514252267014565 00000000000000SPAWNÌ16384Ö0 variable: SPAWN argloopÌ524288Ö0 other: argloop argloop_endÌ524288Ö0 other: argloop_end autocloseÌ16384Ö0 variable: autoclose geany-2.0/tests/ctags/interfaces.f90.tags0000644000175000017500000000062714514252267015257 00000000000000Func1Ì16ÎHasInterfacesÖ0 function: HasInterfaces :: Func1 Func2Ì16ÎHasInterfacesÖ0 function: HasInterfaces :: Func2 HasInterfacesÌ256Ö0 namespace: HasInterfaces MainÌ2048Ö0 struct: Main MyFuncÌ32ÎHasInterfacesÖ0 interface: HasInterfaces :: MyFunc MySubroutineÌ32ÎMainÖ0 interface: Main :: MySubroutine anon_interface_1Ì32ÎHasInterfacesÖ1 interface: HasInterfaces :: anon_interface_1 flags: 1 geany-2.0/tests/ctags/members.f90.tags0000644000175000017500000000063314514252267014563 00000000000000HasMembersÌ1ÎMembersÖ0 class: Members :: HasMembers MembersÌ256Ö0 namespace: Members MyMethodÌ64ÎHasMembersÖ0 member: HasMembers :: MyMethod MySubroutineÌ128Í(arg)ÎMembersÖ0 method: Members :: MySubroutine(arg) kind_memberÌ64ÎHasMembersÖ0 member: HasMembers :: kind_member len_memberÌ64ÎHasMembersÖ0 member: HasMembers :: len_member memberÌ64ÎHasMembersÖ0 member: HasMembers :: member geany-2.0/tests/ctags/make-parentheses.mak0000644000175000017500000000010014514252267015567 00000000000000A=X.c B=Y.c $(A)-$(A:.c=.o): echo $@ ${B}-${B:.c=.o}: echo $@ geany-2.0/tests/ctags/keyword_explicit.cs0000644000175000017500000000100314514252267015560 00000000000000// cs_keyword_explicit.cs using System; struct Digit { byte value; public Digit(byte value) { if (value<0 || value>9) throw new ArgumentException(); this.value = value; } // define explicit byte-to-Digit conversion operator: public static explicit operator Digit(byte b) { Console.WriteLine("conversion occurred"); return new Digit(b); } } class Test { public static void Main() { byte b = 3; Digit d = (Digit)b; // explicit conversion } } geany-2.0/tests/ctags/bug620288.f.tags0000644000175000017500000000006214514252267014223 00000000000000barÌ16Ö0 function: bar fooÌ16Ö0 function: foo geany-2.0/tests/ctags/tabindent.py.tags0000644000175000017500000000034414514252267015132 00000000000000find_headingÌ16Í(self, position=0, direction=Direction.FORWARD, heading=Heading, connect_with_document=True)Ö0 function: find_heading(self, position=0, direction=Direction.FORWARD, heading=Heading, connect_with_document=True) geany-2.0/tests/ctags/process_order_2.h0000644000175000017500000000003214514252267015110 00000000000000enum { I2_E1, I2_E2, }; geany-2.0/tests/ctags/cxx11-noexcept.cpp.tags0000644000175000017500000000030714514252267016102 00000000000000BaseÌ1Ö0 class: Base barÌ1024Í() constÎBaseÖ0Ïvoid prototype: void Base :: bar() const bazÌ16Í()ÎBaseÖ0Ïint function: int Base :: baz() fooÌ1024Í()ÎBaseÖ0Ïvoid prototype: void Base :: foo() geany-2.0/tests/ctags/process_order_1.h0000644000175000017500000000003214514252267015107 00000000000000enum { I1_E1, I1_E2, }; geany-2.0/tests/ctags/block.f900000644000175000017500000000157414514252267013273 00000000000000module Blocks implicit none integer :: i contains function MyFunc(thing) integer, intent(in) :: thing integer :: myfunc block ! these obviously won't show up, because variables inside functions inside modules don't anyway ! and that's fine integer :: tempint tempint = 1 if (tempint == 1) then tempint = 2 end if myfunc = tempint end block end function MyFunc end module Blocks program Main use Blocks implicit none ! these variable declarations should definitely show up in the symbol list integer :: otherint, moreint otherint = 3 block ! These shouldn't, because... integer :: newtempint newtempint = 2 block ! ...the damn things can be arbitrarily nested! integer :: newer_int newer_int = 3 end block newtempint = 2 * newtempint end block end program Main geany-2.0/tests/ctags/strings.php.tags0000644000175000017500000000031414514252267015007 00000000000000aÌ16384Ö0 variable: a bÌ16384Ö0 variable: b cÌ16384Ö0 variable: c dÌ16384Ö0 variable: d eÌ16384Ö0 variable: e fÌ16384Ö0 variable: f gÌ16384Ö0 variable: g zzz_endÌ16384Ö0 variable: zzz_end geany-2.0/tests/ctags/angle_bracket.cpp.tags0000644000175000017500000000023414514252267016073 00000000000000barÌ16Í(int value)Ö0Ïvoid function: void bar(int value) bar2Ì16Í(void)Ö0 function: bar2(void) fooÌ16Í(int nelem)Ö0Ïvoid function: void foo(int nelem) geany-2.0/tests/ctags/keyword_class.cs.tags0000644000175000017500000000064414514252267016013 00000000000000KidÌ1Ö0 class: Kid KidÌ128Í()ÎKidÖ0 method: Kid :: Kid() KidÌ128Í(string name, int age)ÎKidÖ0 method: Kid :: Kid(string name, int age) MainÌ128Í()ÎMainClassÖ0Ïpublic void method: public void MainClass :: Main() MainClassÌ1Ö0 class: MainClass PrintKidÌ128Í()ÎKidÖ0Ïpublic void method: public void Kid :: PrintKid() ageÌ8ÎKidÖ0Ïint field: int Kid :: age nameÌ8ÎKidÖ0 field: Kid :: name geany-2.0/tests/ctags/keyword_interface.cs.tags0000644000175000017500000000073114514252267016643 00000000000000IPointÌ32Ö0 interface: IPoint MainÌ128Í()ÎMainClassÖ0Ïpublic void method: public void MainClass :: Main() MainClassÌ1Ö0 class: MainClass MyPointÌ1Ö0 class: MyPoint MyPointÌ128Í(int x, int y)ÎMyPointÖ0 method: MyPoint :: MyPoint(int x, int y) PrintPointÌ128Í(IPoint p)ÎMainClassÖ0Ïprivate void method: private void MainClass :: PrintPoint(IPoint p) myXÌ8ÎMyPointÖ0Ïint field: int MyPoint :: myX myYÌ8ÎMyPointÖ0Ïint field: int MyPoint :: myY geany-2.0/tests/ctags/titles.t2t0000644000175000017500000000235014514252267013611 00000000000000 % from rules.t2t, with unique title content as our output removed % duplicate tags (even with different scopes) %%% Syntax: Balanced equal signs (from 1 to 5) = First Title Level 1 = == First Title Level 2 == === First Title Level 3 === ==== First Title Level 4 ==== ===== First Title Level 5 ===== %%% Label: Between brackets, alphanumeric [A-Za-z0-9_-] = Second Title Level 1 =[lab_el-1] == Second Title Level 2 ==[lab_el-2] === Second Title Level 3 ===[lab_el-3] ==== Second Title Level 4 ====[lab_el-4] ===== Second Title Level 5 =====[lab_el-5] %%% Syntax: Spaces around and/or inside are allowed (and ignored) ===Third Title Level 3=== === Fourth Title Level 3 === === Fifth Title Level 3 === === Sixth Title Level 3 === === Seventh Title Level 3 === === Eighth Title Level 3 ===[lab_el-9] %%% Invalid: Unbalanced equal signs =First Not Title ==Second Not Title= ===Third Not Title==== %%% Invalid: Level deeper than 5 ======First Not Title 6====== =======First Not Title 7======= %%% Invalid: Space between title and label =Fourth Not Title= [label1] %%% Invalid: Space inside label =Fifth Not Title=[ label ] %%% Invalid: Strange chars inside label =Sixth Not Title=[la/bel] geany-2.0/tests/ctags/labels.sql.tags0000644000175000017500000000006214514252267014570 00000000000000outer_procedureÌ256Ö0 namespace: outer_procedure geany-2.0/tests/ctags/bug1458930.c.tags0000644000175000017500000000012214514252267014301 00000000000000xÌ1024Í()Ö0Ïchar prototype: char x() yÌ1024Í()Ö0Ïwchar_t prototype: wchar_t y() geany-2.0/tests/ctags/cxx11enum.cpp.tags0000644000175000017500000000116214514252267015144 00000000000000AÌ2Ö0Ïint enum: int A A_aÌ4ÎAÖ0 enumerator: A :: A_a A_bÌ4ÎAÖ0 enumerator: A :: A_b A_cÌ4ÎAÖ0 enumerator: A :: A_c BÌ2Ö0Ïlong enum: long B B_aÌ4ÎBÖ0 enumerator: B :: B_a B_bÌ4ÎBÖ0 enumerator: B :: B_b B_cÌ4ÎBÖ0 enumerator: B :: B_c CÌ2Ö0Ïunsigned int enum: unsigned int C C_aÌ4ÎCÖ0 enumerator: C :: C_a C_bÌ4ÎCÖ0 enumerator: C :: C_b C_cÌ4ÎCÖ0 enumerator: C :: C_c DÌ2ÎFooÖ0Ïint enum: int Foo :: D FooÌ1Ö0 class: Foo aÌ4ÎFoo::DÖ0 enumerator: Foo::D :: a bÌ4ÎFoo::DÖ0 enumerator: Foo::D :: b cÌ4ÎFoo::DÖ0 enumerator: Foo::D :: c fooÌ1024Í(enum D a)ÎFooÖ0Ïvoid prototype: void Foo :: foo(enum D a) geany-2.0/tests/ctags/bug1830343.cs.tags0000644000175000017500000000021014514252267014452 00000000000000ForEachTestÌ1Ö0 class: ForEachTest MainÌ128Í(string[] args)ÎForEachTestÖ0Ïvoid method: void ForEachTest :: Main(string[] args) geany-2.0/tests/ctags/db-trig.sql0000644000175000017500000000171114514252267013723 00000000000000rem ----------------------------------------------------------------------- rem URL: http://www.orafaq.com/scripts/plsql/db-trig.txt rem Filename: db-trig.sql rem Purpose: Demonstrate database triggers (available from Oracle 8i) rem Need DBA or CREATE ANY TRIGGER privs rem Date: 28-Aug-1998 rem Author: Frank Naude (frank@ibi.co.za) rem ----------------------------------------------------------------------- create or replace trigger restrict_login after logon on database declare flag number := 0; begin select 1 into flag from sys.v_$session where program like '%sqlplus%'; if flag = 1 then raise_application_error(-20000, 'No access from sqlplus'); end if; end; / show errors CREATE OR REPLACE TRIGGER startup_db after startup on database begin dbms_shared_pool.keep ('SYS.STANDARD','P'); dbms_shared_pool.keep ('SYS.DBMS_STANDARD','P'); end; / show errors geany-2.0/tests/ctags/tabindent.py0000644000175000017500000000017014514252267014172 00000000000000def find_heading(self, position=0, direction=Direction.FORWARD, \ heading=Heading, connect_with_document=True): pass geany-2.0/tests/ctags/keyword_volatile.cs0000644000175000017500000000023114514252267015560 00000000000000// csharp_volatile.cs class Test { public volatile int i; Test(int _i) { i = _i; } public static void Main() { } } geany-2.0/tests/ctags/keyword_explicit.cs.tags0000644000175000017500000000051214514252267016521 00000000000000DigitÌ128Í(byte value)ÎDigitÖ0 method: Digit :: Digit(byte value) DigitÌ2048Ö0 struct: Digit MainÌ128Í()ÎTestÖ0Ïpublic void method: public void Test :: Main() TestÌ1Ö0 class: Test operator DigitÌ128Í(byte b)ÎDigitÖ0 method: Digit :: operator Digit(byte b) valueÌ8ÎDigitÖ0Ïbyte field: byte Digit :: value geany-2.0/tests/ctags/bug2117073.java0000644000175000017500000000060014514252267014033 00000000000000public class AAssignmentExp { public AAssignmentExp(@SuppressWarnings("hiding") TAssign _token_, @SuppressWarnings("hiding") PLvalue _lvalue_, @SuppressWarnings("hiding") PExp _exp_) { setToken(_token_); setLvalue(_lvalue_); setExp(_exp_); } @Override void removeChild(@SuppressWarnings("unused") Node child) { } } geany-2.0/tests/ctags/whitespaces.php.tags0000644000175000017500000000032014514252267015632 00000000000000aÌ16Í()Ö0 function: a() bÌ16Í()Ö0 function: b() cÌ16Í()Ö0 function: c() dÌ16Í()Ö0 function: d() eÌ16Í()Ö0 function: e() fÌ16Í()Ö0 function: f() gÌ16Í()Ö0 function: g() hÌ16Í()Ö0 function: h() geany-2.0/tests/ctags/ruby-block-call.rb.tags0000644000175000017500000000011014514252267016106 00000000000000nothingÌ128Í()Ö0 method: nothing() plopÌ128Í()Ö0 method: plop() geany-2.0/tests/ctags/namespaces.php.tags0000644000175000017500000000105314514252267015436 00000000000000BÌ1ÎBar::BazÖ0 class: Bar::Baz :: B Bar\BazÌ256Ö0 namespace: Bar\Baz CÌ1ÎFooÖ0 class: Foo :: C FooÌ256Ö0 namespace: Foo __constructÌ16Í()ÎBar::Baz::BÖ0 function: Bar::Baz::B :: __construct() __constructÌ16Í()ÎFoo::CÖ0 function: Foo::C :: __construct() aÌ16Í()ÎBar::BazÖ0 function: Bar::Baz :: a() aÌ16Í()ÎFooÖ0 function: Foo :: a() bÌ16Í()ÎFooÖ0 function: Foo :: b() cÌ16Í()ÎBar::Baz::BÖ0 function: Bar::Baz::B :: c() dÌ16Í()ÎFoo::CÖ0 function: Foo::C :: d() inRootÌ16Í()Ö0 function: inRoot() meTooÌ16Í()Ö0 function: meToo() geany-2.0/tests/ctags/pure_elem.f95.tags0000644000175000017500000000021614514252267015110 00000000000000FÌ16Ö0 function: F elem_maxabsÌ16Ö0 function: elem_maxabs pure_funcÌ16Ö0 function: pure_func pure_maxabs2Ì16Ö0 function: pure_maxabs2 geany-2.0/tests/ctags/python-comments.py.tags0000644000175000017500000000003414514252267016322 00000000000000fooÌ32768Ö0 externvar: foo geany-2.0/tests/ctags/initialization.f90.tags0000644000175000017500000000020014514252267016146 00000000000000funconÌ256Ö0 namespace: funcon imatÌ16384ÎfunconÖ0 variable: funcon :: imat imat6Ì16384ÎfunconÖ0 variable: funcon :: imat6 geany-2.0/tests/ctags/bracematch.js0000644000175000017500000000125714514252267014306 00000000000000/* * "Braces aren't properly matched in findCmdTerm()" * * ctags -f - bracematch.js should output: * * functions: * Container * Container.x * Container.y * * classes: * MyClass * * methods: * MyClass.insert * MyClass.wrap */ function Container() { function x() { if (!x) x = { }; } function y() { } } // from prototype.js, a lot simplified to only show the issue MyClass = { insert: function(element, insertions) { element = $(element); if (condition) insertions = {bottom:insertions}; var content, insert, tagName, childNodes; }, wrap: function(element, wrapper, attributes) { // ... } } geany-2.0/tests/ctags/enumerators.f90.tags0000644000175000017500000000262214514252267015475 00000000000000Aster_colonÌ2ÎEnumsÖ0 enum: Enums :: Aster_colon Aster_kindÌ2ÎEnumsÖ0 enum: Enums :: Aster_kind BodyPartÌ2ÎEnumsÖ0 enum: Enums :: BodyPart ColonsÌ2ÎEnumsÖ0 enum: Enums :: Colons EnumsÌ256Ö0 namespace: Enums FuncÌ16ÎEnumsÖ0 function: Enums :: Func Name_colonÌ2ÎEnumsÖ0 enum: Enums :: Name_colon Paren_colonÌ2ÎEnumsÖ0 enum: Enums :: Paren_colon Paren_kindÌ2ÎEnumsÖ0 enum: Enums :: Paren_kind anon_enum_1Ì2ÎEnumsÖ1 enum: Enums :: anon_enum_1 flags: 1 anon_enum_2Ì2ÎEnumsÖ1 enum: Enums :: anon_enum_2 flags: 1 armÌ4ÎBodyPartÖ0 enumerator: BodyPart :: arm bÌ4ÎParen_kindÖ0 enumerator: Paren_kind :: b blueÌ4Îanon_enum_1Ö0 enumerator: anon_enum_1 :: blue bronzeÌ4Îanon_enum_1Ö0 enumerator: anon_enum_1 :: bronze cÌ4ÎAster_kindÖ0 enumerator: Aster_kind :: c dÌ4ÎName_colonÖ0 enumerator: Name_colon :: d dÌ4ÎParen_colonÖ0 enumerator: Paren_colon :: d eÌ4ÎAster_colonÖ0 enumerator: Aster_colon :: e goldÌ4Îanon_enum_1Ö0 enumerator: anon_enum_1 :: gold legÌ4ÎBodyPartÖ0 enumerator: BodyPart :: leg no_c_bindingÌ4Îanon_enum_2Ö0 enumerator: anon_enum_2 :: no_c_binding othervarÌ16384ÎEnumsÖ0 variable: Enums :: othervar purpleÌ4Îanon_enum_1Ö0 enumerator: anon_enum_1 :: purple rÌ4ÎColonsÖ0 enumerator: Colons :: r redÌ4Îanon_enum_1Ö0 enumerator: anon_enum_1 :: red silverÌ4Îanon_enum_1Ö0 enumerator: anon_enum_1 :: silver somevarÌ16384ÎEnumsÖ0 variable: Enums :: somevar geany-2.0/tests/ctags/vhdl-port.vhd.tags0000644000175000017500000000047714514252267015241 00000000000000aÌ16384Îlogical_ops_1Ö0 variable: logical_ops_1 :: a bÌ16384Îlogical_ops_1Ö0 variable: logical_ops_1 :: b cÌ16384Îlogical_ops_1Ö0 variable: logical_ops_1 :: c dÌ16384Îlogical_ops_1Ö0 variable: logical_ops_1 :: d logical_ops_1Ì1Ö0 class: logical_ops_1 mÌ16384Îlogical_ops_1Ö0 variable: logical_ops_1 :: m geany-2.0/tests/ctags/bug1988026.py0000644000175000017500000000021314514252267013557 00000000000000 class testClass: my_var = 0 def main(): pass if __name__ == '__main__': testClass.main() def im_a_function(): pass geany-2.0/tests/ctags/simple.ps10000644000175000017500000000526414514252267013577 00000000000000# pseudo #!/PowerShell :) # # test file for the CTags/Geany PowerShell tag parser # based on real world code but simplified for automated tests <# multiline comment including a function and variable, both should be ignored: $IgnoreThisVaribale = "Stop" function IgnoreThisFunction($arg1) { Write-Host "dummy" } #> # immediately stop the script if an errors occurs $ErrorActionPreference = "Stop" # a global scoped variable $Global:Settings = $null # a local scoped variable $Local:ALocalVar = $null # a usual variable $BasePath = split-path -parent $Global:MyInvocation.InvocationName FUNCTION Read-Configuration-File() { $Hostname = [System.Environment]::MachineName $ConfigurationFileName = $BasePath + "\script-${Hostname}.conf" LogMessage "Read configuration '${ConfigurationFileName}'" $ConfigFileContent = Get-Content -raw $ConfigurationFileName $Global:Settings = Convertfrom-Stringdata $ConfigFileContent } Function LogMessageOK() { $x = [Console]::WindowWidth - 6 $y = [Console]::CursorTop Try { [Console]::setcursorposition($x, $y) } Catch [system.exception] { # intentionally left empty for redirect of outputs to file } Write-Host -foregroundcolor "green" "[ok]" } function LogMessage() { param( [Parameter(Mandatory=$false)][switch] $NoNewLine, [Parameter(Mandatory=$true)][string] $Message ) $Date = Get-Date -UFormat "%Y-%m-%d %T: " Write-Host -foregroundcolor "yellow" -NoNewLine $Date if ($NoNewLine) { Write-Host -foregroundcolor "green" -NoNewLine $Message } else { Write-Host -foregroundcolor "green" $Message } } function global:A-Global-Scope-Function() { Write-Host "dummy" } filter Script:MyFilter { filter-something } Filter Private:MyPrivateFilter { filter-something } function LoadTemplate($template) { # woah, this is real magic, # see http://stackoverflow.com/questions/10754582/string-interpolation-of-hashtable-values-in-powershell # Set all unbound variables (@args) in the local context while ($args) { ($key, $val, $args) = $args Set-Variable -Name $key.SubString(1, $key.Length-2) -Value $val } $ExecutionContext.InvokeCommand.ExpandString($template) } function TopLevelFunction() { function SecondLevelNestedFunction() { function ThirdLevelNestedFunction() { doSomething() } ThirdLevelNestedFunction } SecondLevelNestedFunction } function Main() { Read-Configuration-File LogMessage $("Working on Environment '{0}'" -f $Settings["EnvironmentName"]) LogMessage "do something ..." Stripped-Down-Code LogMessageOK } Main geany-2.0/tests/ctags/invalid_name.f900000644000175000017500000000061114514252267014616 00000000000000! Test of parsing type with invalid name Module TR_DetectionRecording Implicit None Save Integer :: DR_Lun Character*1024 DR_Filename Type Detection_Record Integer(2) :: Activity Integer(2) :: Type ! "Type" not valid entity name Integer(2) :: Face End Type Detection_Record End Module TR_DetectionRecording geany-2.0/tests/ctags/ruby-sf-bug-364.rb.tags0000644000175000017500000000036014514252267015607 00000000000000DÌ1Ö0 class: D _a?Ì64Í()ÎDÖ0 member: D :: _a?() _b!Ì64Í()ÎDÖ0 member: D :: _b!() _c=Ì64Í(a)ÎDÖ0 member: D :: _c=(a) x?Ì64Í()ÎDÖ0 member: D :: x?() y!Ì64Í()ÎDÖ0 member: D :: y!() z=Ì64Í(a)ÎDÖ0 member: D :: z=(a) geany-2.0/tests/ctags/procedure_pointer_module.f90.tags0000644000175000017500000000034614514252267020227 00000000000000aÌ16384Îproc_pointerÖ0 variable: proc_pointer :: a my_pointerÌ16384Îproc_pointerÖ0 variable: proc_pointer :: my_pointer proc_pointerÌ256Ö0 namespace: proc_pointer subÌ128Í(x)Îproc_pointerÖ0 method: proc_pointer :: sub(x) geany-2.0/tests/ctags/bug2075402.py.tags0000644000175000017500000000006014514252267014476 00000000000000xÌ16384Ö0 variable: x yÌ16384Ö0 variable: y geany-2.0/tests/ctags/bug2886870.tex.tags0000644000175000017500000000314214514252267014675 00000000000000Common Greek lettersÌ65536ÎSpecial SymbolsÖ0 macro: Special Symbols :: Common Greek letters EquationsÌ64Ö0 member: Equations FiguresÌ64Ö0 member: Figures IntroductionÌ64Ö0 member: Introduction ListsÌ64Ö0 member: Lists Literal textÌ64Ö0 member: Literal text Special SymbolsÌ64Ö0 member: Special Symbols Special symbolsÌ65536ÎSpecial SymbolsÖ0 macro: Special Symbols :: Special symbols TablesÌ64Ö0 member: Tables Test for ctagsÌ16384ÎSpecial Symbols""Common Greek lettersÖ0 variable: Special Symbols""Common Greek letters :: Test for ctags \color{red}Use of ColorÌ64Ö0 member: \color{red}Use of Color \label{morefig}SubfiguresÌ64Ö0 member: \label{morefig}Subfigures \lbÌ16Ö0 function: \lb \rbÌ16Ö0 function: \rb \rvÌ16Ö0 function: \rv alignÌ1Ö0 class: align casesÌ1Ö0 class: cases centerÌ1Ö0 class: center commentÌ1Ö0 class: comment documentÌ1Ö0 class: document enumerateÌ1Ö0 class: enumerate eq:fineÌ2048Ö0 struct: eq:fine eq:isingÌ2048Ö0 struct: eq:ising eq:mdivÌ2048Ö0 struct: eq:mdiv equationÌ1Ö0 class: equation fig:ljÌ2048Ö0 struct: fig:lj fig:qm/complexfunctionsÌ2048Ö0 struct: fig:qm/complexfunctions fig:typicalÌ2048Ö0 struct: fig:typical figureÌ1Ö0 class: figure itemizeÌ1Ö0 class: itemize latexÌ8Ö0 field: latex pmatrixÌ1Ö0 class: pmatrix subequationsÌ1Ö0 class: subequations tab:5/tcÌ2048Ö0 struct: tab:5/tc tableÌ1Ö0 class: table tabularÌ1Ö0 class: tabular thebibliographyÌ1Ö0 class: thebibliography verbatimÌ1Ö0 class: verbatim websiteÌ8Ö0 field: website geany-2.0/tests/ctags/shebang.js0000644000175000017500000000004614514252267013617 00000000000000#!/usr/bin/end nodejs function f(){} geany-2.0/tests/ctags/ruby-namespaced-class.rb.tags0000644000175000017500000000012214514252267017311 00000000000000AÌ256Ö0 namespace: A BÌ256ÎAÖ0 namespace: A :: B CÌ1ÎA.BÖ0 class: A.B :: C geany-2.0/tests/ctags/mode.php.tags0000644000175000017500000000040414514252267014242 00000000000000aÌ16Í()Ö0 function: a() bÌ16Í()Ö0 function: b() cÌ16Í()Ö0 function: c() dÌ16Í()Ö0 function: d() eÌ16Í()Ö0 function: e() fÌ16Í()Ö0 function: f() gÌ16Í()Ö0 function: g() hÌ16Í()Ö0 function: h() iÌ16Í()Ö0 function: i() jÌ16Í()Ö0 function: j() geany-2.0/tests/ctags/numlib.f900000644000175000017500000000441614514252267013465 00000000000000! Bug reported by Brian Helinski on 4 Feb 2003 module numerical_libraries interface subroutine a2ald (nf, nl, y, nrf, indrf, nef, nfef, indef, conper, iprint& , model, aov, ems, vc, ldvc, ymeans, wk, iwk, c13ksp) integer, intent(in) :: nf integer, dimension(*), intent(in) :: nl real(kind(1e0)), dimension(*) :: y integer, intent(in) :: nrf integer, dimension(*), intent(in) :: indrf integer, intent(in) :: nef integer, dimension(*), intent(in) :: nfef integer, dimension(*), intent(in) :: indef real(kind(1e0)), intent(in) :: conper integer, intent(in) :: iprint integer, intent(in) :: model real(kind(1e0)), dimension(*), intent(in) :: aov real(kind(1e0)), dimension(*), intent(inout) :: ems real(kind(1e0)), dimension(ldvc,*), intent(inout) :: vc integer, intent(in) :: ldvc real(kind(1e0)), dimension(*), intent(in) :: ymeans real(kind(1e0)), dimension(*), intent(inout) :: wk integer, dimension(*), intent(in) :: iwk character (len = 13), dimension(*), intent(out) :: c13ksp end subroutine subroutine b2lsf (fcn, m, n, xguess, ibtype, xlb, xub, xscale, fscale& , iparam, rparam, x, fvec, fjac, ldfjac, wk, iwk) integer, intent(in) :: m integer, intent(in) :: n real(kind(1e0)), dimension(*) :: xguess integer, intent(in) :: ibtype real(kind(1e0)), dimension(*), intent(inout) :: xlb real(kind(1e0)), dimension(*), intent(inout) :: xub real(kind(1e0)), dimension(*) :: xscale real(kind(1e0)), dimension(*) :: fscale integer, dimension(*) :: iparam real(kind(1e0)), dimension(*) :: rparam real(kind(1e0)), dimension(*) :: x real(kind(1e0)), dimension(*) :: fvec real(kind(1e0)), dimension(*) :: fjac integer, intent(in) :: ldfjac real(kind(1e0)), dimension(*) :: wk integer, dimension(*) :: iwk interface subroutine fcn(m, n, x, f) integer, intent(in) :: m, n real(kind(1e0)), intent(in) :: x(*) real(kind(1e0)), intent(out) :: f(*) end subroutine end interface end subroutine END INTERFACE end module geany-2.0/tests/ctags/keyword_protected.cs0000644000175000017500000000053414514252267015740 00000000000000// protected_keyword.cs using System; class MyClass { protected int x; protected int y; } class MyDerivedC: MyClass { public static void Main() { MyDerivedC mC = new MyDerivedC(); // Direct access to protected members: mC.x = 10; mC.y = 15; Console.WriteLine("x = {0}, y = {1}", mC.x, mC.y); } } geany-2.0/tests/ctags/fortran_associate.f90.tags0000644000175000017500000000040514514252267016634 00000000000000aÌ16384Îwith_associateÖ0 variable: with_associate :: a do_other_stuffÌ128Í(a)Îwith_associateÖ0 method: with_associate :: do_other_stuff(a) do_stuffÌ16Îwith_associateÖ0 function: with_associate :: do_stuff with_associateÌ256Ö0 namespace: with_associate geany-2.0/tests/ctags/bug2374109.vhd0000644000175000017500000000030414514252267013701 00000000000000function Pow2( N, Exp : integer ) return mylib.myinteger is Variable Result : integer := 1; begin for i in 1 to Exp loop Result := Result * N; end loop; return( Result ); end Pow; geany-2.0/tests/ctags/bug726712.f90.tags0000644000175000017500000000017114514252267014374 00000000000000sub1Ì128Í(a)Ö0 method: sub1(a) sub2Ì128Í(a)Ö0 method: sub2(a) tagstest_ctrlÌ128Í()Ö0 method: tagstest_ctrl() geany-2.0/tests/ctags/simple.d.tags0000644000175000017500000000222114514252267014242 00000000000000AliasIntÌ4096Ö0 typedef: AliasInt ClassÌ1Ö0 class: Class EnumÌ2Ö0 enum: Enum InterfaceÌ32Ö0 interface: Interface StructÌ2048Ö0 struct: Struct TemplateÌ256Ö0 namespace: Template TemplateAliasÌ4096ÎTemplateÖ0 typedef: Template :: TemplateAlias UnionÌ8192ÎStructÖ0 union: Struct :: Union _barÌ64ÎClassÖ0ÏAliasInt member: AliasInt Class :: _bar barÌ4ÎEnumÖ0 enumerator: Enum :: bar barÌ16Í()ÎClassÖ0Ïpublic AliasInt function: public AliasInt Class :: bar() barÌ1024Í()ÎInterfaceÖ0Ïpublic AliasInt prototype: public AliasInt Interface :: bar() conditionalÌ16384Ö0ÏT variable: T conditional fooÌ4ÎEnumÖ0 enumerator: Enum :: foo globalVarÌ16384Ö0Ï__gshared int variable: __gshared int globalVar iÌ16384Ö0Ïint variable: int i mainÌ16Í(string[] args)Ö0Ïvoid function: void main(string[] args) objÌ16384Ö0ÏObject variable: Object obj qarÌ64ÎStruct.UnionÖ0Ïint member: int Struct.Union :: qar quxxÌ64ÎStruct.UnionÖ0Ïbool member: bool Struct.Union :: quxx test.simpleÌ256Ö0 namespace: test.simple tfunÌ16Í(T v)ÎClassÖ0Ïauto function: auto Class :: tfun(T v) thisÌ16Í(AliasInt x)ÎClassÖ0 function: Class :: this(AliasInt x) geany-2.0/tests/ctags/dopbl2.f.tags0000644000175000017500000000003714514252267014140 00000000000000DOPBL2Ì16Ö0 function: DOPBL2 geany-2.0/tests/ctags/1795612.js0000644000175000017500000000074214514252267013051 00000000000000 // This file should generate the following tags: // classes // Test.RPC // methods // Test.RPC.asyncMethod // Test.RPC.asyncRequest // properties // Test.RPC.request_id Test.RPC = { request_id: 0, asyncRequest: function( /* string */ uri, /* object */ data, /* object */ callback) { }, asyncMethod: function( /* string */ uri, /* string */ method, /* array */ params, /* object */ callback) { } }; geany-2.0/tests/ctags/bug1020715.cpp0000644000175000017500000000006114514252267013670 00000000000000void f() { done(a<<1); a->a; if (a->a) { } } geany-2.0/tests/ctags/bug612621.pl0000644000175000017500000000230314514252267013444 00000000000000=pod Bugs item #612621, was opened at 2002-09-21 21:23 You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=106556&aid=612621&group_id=6556 Category: None Group: None Status: Open Resolution: None Priority: 5 Submitted By: Richard Donkin (rdonkin) Assigned to: Nobody/Anonymous (nobody) Summary: Perl POD syntax -> incomplete tags file Initial Comment: In the following test file, ctags 5.2.3 (compiled from source on Cygwin) only adds the first subroutine (bar) to the tags file, when run using: ctags --totals -- language-force=perl temp ----------------- =cut sub bar() { print "blah\n"; =for print "blah2\n"; # Note: next line has trailing space =cut } sub foo { print "hello\n"; } =pod The tags file looks like this: !_TAG_FILE_FORMAT 2 /extended format; -- format=1 will not append ;" to lines/ !_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted/ !_TAG_PROGRAM_AUTHOR Darren Hiebert /dhiebert@users.sourceforge.net/ !_TAG_PROGRAM_NAME Exuberant Ctags // !_TAG_PROGRAM_URL http://ctags.sourceforge.net /official site/ !_TAG_PROGRAM_VERSION 5.2.3 // bar temp /^sub bar() {$/;" s The workaround is to delete the trailing space at the end of the '=cut' line. =cut geany-2.0/tests/ctags/enum.f900000644000175000017500000000164114514252267013140 00000000000000module Constants implicit none real, parameter :: pi = 4 * atan(1.0) real, parameter :: E_e = 510998.91013 ! we now have enumerators in F2003/8, for the sake of interop with C enum, bind(c) ! unnamed 1 enumerator :: red =1, blue, black =5 enumerator yellow enumerator gold, silver, bronze enumerator :: purple enumerator :: pink, lavender end enum enum ! unnamed 2 enumerator :: a, b, c end enum enum :: Named1 enumerator :: x1, y1, z1 end enum enum Named2 enumerator :: x2, y2, z2 end enum enum(8) Named3 enumerator :: x3, y3, z3 end enum enum*8 Named4 enumerator :: x4, y4, z4 end enum enum(8) :: Named5 enumerator :: x5, y5, z5 end enum enum*8 :: Named6 enumerator :: x6, y6, z6 end enum enum, bind(c) :: Named7 enumerator :: x7, y7, z7 end enum real, parameter :: hc = 12398.4193 public end module Constants geany-2.0/tests/ctags/simple.clj0000644000175000017500000000040514514252267013634 00000000000000(ns app.controller) (defn empty-fn []) (defn function-with-body [] (println "body")) (clojure.core/defn core-function-with-body [] (println "core")) '(defn quoted-function []) (quote quoted-function2 []) (clojure.core/ns another.name) (defn x []) geany-2.0/tests/ctags/make-target-with-parentheses.mak.tags0000644000175000017500000000011714514252267020771 00000000000000$(obj)/raid6int1.cÌ16Ö0 function: $(obj)/raid6int1.c FÌ65536Ö0 macro: F geany-2.0/tests/ctags/bug1764148.py0000644000175000017500000000005514514252267013560 00000000000000#!/usr/bin/python def PyFunc(msg): print msg geany-2.0/tests/ctags/anonymous_functions.php.tags0000644000175000017500000000035314514252267017441 00000000000000_gÌ16384Ö0 variable: _g aÌ16Í()Ö0 function: a() bÌ16Í($x, $y)Ö0 function: b($x, $y) cÌ16Í()Ö0 function: c() dÌ16Í()Ö0 function: d() eÌ16Í()Ö0 function: e() fÌ16Í()Ö0 function: f() f_subÌ16Í()ÎfÖ0 function: f :: f_sub() geany-2.0/tests/ctags/traffic_signal.v.tags0000644000175000017500000000124314514252267015751 00000000000000amberÌ16384ÎtrafficÖ0 variable: traffic :: amber amber_ticsÌ16384ÎtrafficÖ0 variable: traffic :: amber_tics clockÌ16384ÎtrafficÖ0 variable: traffic :: clock colorÌ16384Îtraffic.lightÖ0 variable: traffic.light :: color greenÌ16384ÎtrafficÖ0 variable: traffic :: green green_ticsÌ16384ÎtrafficÖ0 variable: traffic :: green_tics lightÌ16ÎtrafficÖ0 function: traffic :: light offÌ16384ÎtrafficÖ0 variable: traffic :: off onÌ16384ÎtrafficÖ0 variable: traffic :: on redÌ16384ÎtrafficÖ0 variable: traffic :: red red_ticsÌ16384ÎtrafficÖ0 variable: traffic :: red_tics ticsÌ16384Îtraffic.lightÖ0 variable: traffic.light :: tics trafficÌ1Ö0 class: traffic geany-2.0/tests/ctags/titles.t2t.tags0000644000175000017500000000443414514252267014553 00000000000000Eighth Title Level 3Ì64ÎSecond Title Level 1""Second Title Level 2Ö0 member: Second Title Level 1""Second Title Level 2 :: Eighth Title Level 3 Fifth Title Level 3Ì64ÎSecond Title Level 1""Second Title Level 2Ö0 member: Second Title Level 1""Second Title Level 2 :: Fifth Title Level 3 First Title Level 1Ì64Ö0 member: First Title Level 1 First Title Level 2Ì64ÎFirst Title Level 1Ö0 member: First Title Level 1 :: First Title Level 2 First Title Level 3Ì64ÎFirst Title Level 1""First Title Level 2Ö0 member: First Title Level 1""First Title Level 2 :: First Title Level 3 First Title Level 4Ì64ÎFirst Title Level 1""First Title Level 2""First Title Level 3Ö0 member: First Title Level 1""First Title Level 2""First Title Level 3 :: First Title Level 4 First Title Level 5Ì64ÎFirst Title Level 1""First Title Level 2""First Title Level 3""First Title Level 4Ö0 member: First Title Level 1""First Title Level 2""First Title Level 3""First Title Level 4 :: First Title Level 5 Fourth Title Level 3Ì64ÎSecond Title Level 1""Second Title Level 2Ö0 member: Second Title Level 1""Second Title Level 2 :: Fourth Title Level 3 Second Title Level 1Ì64Ö0 member: Second Title Level 1 Second Title Level 2Ì64ÎSecond Title Level 1Ö0 member: Second Title Level 1 :: Second Title Level 2 Second Title Level 3Ì64ÎSecond Title Level 1""Second Title Level 2Ö0 member: Second Title Level 1""Second Title Level 2 :: Second Title Level 3 Second Title Level 4Ì64ÎSecond Title Level 1""Second Title Level 2""Second Title Level 3Ö0 member: Second Title Level 1""Second Title Level 2""Second Title Level 3 :: Second Title Level 4 Second Title Level 5Ì64ÎSecond Title Level 1""Second Title Level 2""Second Title Level 3""Second Title Level 4Ö0 member: Second Title Level 1""Second Title Level 2""Second Title Level 3""Second Title Level 4 :: Second Title Level 5 Seventh Title Level 3Ì64ÎSecond Title Level 1""Second Title Level 2Ö0 member: Second Title Level 1""Second Title Level 2 :: Seventh Title Level 3 Sixth Title Level 3Ì64ÎSecond Title Level 1""Second Title Level 2Ö0 member: Second Title Level 1""Second Title Level 2 :: Sixth Title Level 3 Third Title Level 3Ì64ÎSecond Title Level 1""Second Title Level 2Ö0 member: Second Title Level 1""Second Title Level 2 :: Third Title Level 3 geany-2.0/tests/ctags/bug639639.h.tags0000644000175000017500000000036414514252267014244 00000000000000Namespace1Ì256Ö0 namespace: Namespace1 anon2Ì4Îanon_enum_1Ö0 enumerator: anon_enum_1 :: anon2 anon_enum_1Ì2Ö1 enum: anon_enum_1 flags: 1 function2Ì1024Í(char * str)ÎNamespace1Ö0Ïint prototype: int Namespace1 :: function2(char * str) geany-2.0/tests/ctags/2023624.js0000644000175000017500000000061614514252267013035 00000000000000/* * Both functions should be tagged. * The embedded quote was fixed in issue: * [ 1878155 ] Javascript escaped quotation mark brakes output * [ 2023712 ] parseString for javascript broken on embedded quote * The fix will be part of the 5.8 release. */ function f1() { var str = 'This function will be listed.'; } function f2() { var str = 'This function won\'t.'; } geany-2.0/tests/ctags/keyword_private.cs0000644000175000017500000000101014514252267015407 00000000000000// private_keyword.cs using System; class Employee { public string name = "xx"; double salary = 100.00; // private access by default private int not_visible = 3; // strangely, not in original example public double AccessSalary() { return salary; } } class MainClass { public static void Main() { Employee e = new Employee(); // Accessing the public field: string n = e.name; // Accessing the private field: double s = e.AccessSalary(); } } geany-2.0/tests/ctags/simple.docbook0000644000175000017500000000213314514252267014504 00000000000000
My first docbook document Seth Kenlon opensource.com 2017 Required Chapter At least one chapter, reference, part, or article is required in a book.
Introduction Introductory text goes here.
Section with a title Main body text goes here. Section with a title Main body text goes here. Section with a title Main body text goes here.
Conclusion Exciting and inspiring conclusion goes here.
Demonstration Appendix
geany-2.0/tests/ctags/bug877956.f900000644000175000017500000000336614514252267013471 00000000000000! Bugs item #877956, was opened at 2004-01-15 17:59 ! Message generated for change (Tracker Item Submitted) made by Item Submitter ! You can respond by visiting: ! https://sourceforge.net/tracker/?func=detail&atid=106556&aid=877956&group_id=6556 ! ! Category: None ! Group: None ! Status: Open ! Resolution: None ! Priority: 5 ! Submitted By: Randy Hood (randy762) ! Assigned to: Nobody/Anonymous (nobody) ! Summary: Broken Fortran variable listing after =-1 ! ! Initial Comment: ! When I run ctags v5.5.2 on Redhat Linux 9 with the command ! ! ctags --Fortran-kinds=v -x test.f90 ! ! where test.f90 is ! ---------------------------------- PROGRAM test IMPLICIT NONE INTEGER :: cm1 =-1, c2 = 2 END PROGRAM test ! ------------------------------------- ! ! I only get this one line of output ! ! cm1 variable 4 test.f90 INTEGER :: cm1 =-1, c2 = 2 ! ! If I change one line of test.f90 so that it is now ! ---------------------------------------- PROGRAM test IMPLICIT NONE INTEGER :: cm1 = -1, c2 = 2 END PROGRAM test ! ----------------------------------------- ! and run the command ! ! ctags --Fortran-kinds=v -x test.f90 ! ! I get this correct output ! ! c2 variable 4 test.f90 INTEGER :: cm1 = -1, c2 = 2 ! cm1 variable 4 test.f90 INTEGER :: cm1 = -1, c2 = 2 ! ! ---------------------------------------------------------------------- ! You can respond by visiting: ! https://sourceforge.net/tracker/?func=detail&atid=106556&aid=877956&group_id=6556 geany-2.0/tests/ctags/keyword_class.cs0000644000175000017500000000164714514252267015062 00000000000000// keyword_class.cs // class example using System; public class Kid { private int age; private string name; // Default constructor: public Kid() { name = "N/A"; } // Constructor: public Kid(string name, int age) { this.name = name; this.age = age; } // Printing method: public void PrintKid() { Console.WriteLine("{0}, {1} years old.", name, age); } } public class MainClass { public static void Main() { // Create objects // Objects must be created using the new operator: Kid kid1 = new Kid("Craig", 11); Kid kid2 = new Kid("Sally", 10); // Create an object using the default constructor: Kid kid3 = new Kid(); // Display results: Console.Write("Kid #1: "); kid1.PrintKid(); Console.Write("Kid #2: "); kid2.PrintKid(); Console.Write("Kid #3: "); kid3.PrintKid(); } } geany-2.0/tests/ctags/js-const.js0000644000175000017500000000013714514252267013751 00000000000000 const A = 1; const B = 1; const Group = { X:1, Y:2, Z:3 }; const func = function () {} geany-2.0/tests/ctags/hex2dec.sql0000644000175000017500000000252614514252267013722 00000000000000rem ----------------------------------------------------------------------- rem URL: http://www.orafaq.com/scripts/plsql/hex2dec.txt rem Filename: hex2dec.sql rem Purpose: Functions to convert Hex to Decimal and vice versa rem Author: Mark Malakanov, Feb-1999 + Anonymous rem ----------------------------------------------------------------------- CREATE OR REPLACE FUNCTION hex2dec (hexnum in char) RETURN number IS i number; digits number; result number := 0; current_digit char(1); current_digit_dec number; BEGIN digits := length(hexnum); for i in 1..digits loop current_digit := SUBSTR(hexnum, i, 1); if current_digit in ('A','B','C','D','E','F') then current_digit_dec := ascii(current_digit) - ascii('A') + 10; else current_digit_dec := to_number(current_digit); end if; result := (result * 16) + current_digit_dec; end loop; return result; END hex2dec; / show errors CREATE OR REPLACE FUNCTION num2hex (N in number) RETURN varchar2 IS H varchar2(64) :=''; N2 integer := N; BEGIN loop select rawtohex(chr(N2))||H into H from dual; N2 := trunc(N2 / 256); exit when N2=0; end loop; return H; END num2hex; / show errors -- Examples: select hex2dec('FF') from dual; select num2hex(10) from dual; geany-2.0/tests/ctags/cxx11-raw-strings.cpp.tags0000644000175000017500000000171714514252267016543 00000000000000FOURÌ65536Ö0 macro: FOUR memb1Ì64Îtyp1Ö0Ïint member: int typ1 :: memb1 memb2Ì64Îtyp2Ö0Ïint member: int typ2 :: memb2 memb3Ì64Îtyp3Ö0Ïint member: int typ3 :: memb3 memb4Ì64Îtyp4Ö0Ïint member: int typ4 :: memb4 memb5Ì64Îtyp5Ö0Ïint member: int typ5 :: memb5 memb6Ì64Îtyp6Ö0Ïint member: int typ6 :: memb6 memb7Ì64Îtyp7Ö0Ïint member: int typ7 :: memb7 str1Ì16384Ö0Ïconst char * variable: const char * str1 str2Ì16384Ö0Ïconst char * variable: const char * str2 str3Ì16384Ö0Ïconst char * variable: const char * str3 str4Ì16384Ö0Ïconst char * variable: const char * str4 str5Ì16384Ö0Ïconst char * variable: const char * str5 str6Ì16384Ö0Ïconst char * variable: const char * str6 str7Ì16384Ö0Ïconst char * variable: const char * str7 typ1Ì2048Ö0 struct: typ1 typ2Ì2048Ö0 struct: typ2 typ3Ì2048Ö0 struct: typ3 typ4Ì2048Ö0 struct: typ4 typ5Ì2048Ö0 struct: typ5 typ6Ì2048Ö0 struct: typ6 typ7Ì2048Ö0 struct: typ7 geany-2.0/tests/ctags/bug1950327.js.tags0000644000175000017500000000153314514252267014477 00000000000000*Ì64Îcontainer.dirtyTabÖ0 member: container.dirtyTab :: * DifferentÌ1Ö0 class: Different TabChromeÌ1Ö0 class: TabChrome createTabTileÌ128Í(browser)ÎDifferentÖ0 method: Different :: createTabTile(browser) createTabTileÌ128Í(browser)ÎTabChromeÖ0 method: TabChrome :: createTabTile(browser) destroyTabTileÌ128Í(tile)ÎDifferentÖ0 method: Different :: destroyTabTile(tile) destroyTabTileÌ128Í(tile)ÎTabChromeÖ0 method: TabChrome :: destroyTabTile(tile) dirtyTabÌ1ÎcontainerÖ0 class: container :: dirtyTab initÌ128Í()ÎDifferentÖ0 method: Different :: init() initÌ128Í()ÎTabChromeÖ0 method: TabChrome :: init() snapshotÌ64Îcontainer.dirtyTabÖ0 member: container.dirtyTab :: snapshot titleÌ64Îcontainer.dirtyTabÖ0 member: container.dirtyTab :: title urlÌ64Îcontainer.dirtyTabÖ0 member: container.dirtyTab :: url geany-2.0/tests/ctags/simple.sh.tags0000644000175000017500000000011114514252267014425 00000000000000_a_bÌ16Ö0 function: _a_b f1Ì16Ö0 function: f1 f2Ì16Ö0 function: f2 geany-2.0/tests/ctags/ada-expression-function.adb.tags0000644000175000017500000000116214514252267020024 00000000000000Another_Boolean_As_StringÌ16ÎTagged_ProcedureÖ0 function: Tagged_Procedure :: Another_Boolean_As_String Boolean_As_StringÌ16ÎTagged_ProcedureÖ0 function: Tagged_Procedure :: Boolean_As_String My_TypeÌ16384ÎTestÖ0 variable: Test :: My_Type Not_Tagged_ProcedureÌ16ÎTestÖ0 function: Test :: Not_Tagged_Procedure Tagged_ProcedureÌ16ÎTestÖ0 function: Test :: Tagged_Procedure TestÌ16Ö0 function: Test Yet_Boolean_As_StringÌ16ÎTagged_ProcedureÖ0 function: Tagged_Procedure :: Yet_Boolean_As_String p0Ì16ÎTagged_ProcedureÖ0 function: Tagged_Procedure :: p0 p1Ì16ÎTagged_ProcedureÖ0 function: Tagged_Procedure :: p1 geany-2.0/tests/ctags/line_directives.c0000644000175000017500000000023414514252267015165 00000000000000/* ANSI format */ # line 10 "a.c" int a; /* GNU C format */ # 20 "b.c" int b; /* obsolete format */ # 30 c.c int c; /* invalid formats */ # 1 OK # 0 Not OK geany-2.0/tests/ctags/bug1020715.c.tags0000644000175000017500000000004414514252267014266 00000000000000fÌ16Í()Ö0Ïvoid function: void f() geany-2.0/tests/ctags/bug3571233.js0000644000175000017500000000225614514252267013542 00000000000000/* * "Functions nested inside methods show improper scope with the parent method * being reported as "function"" * * ctags -f - bug3571233.js should output: * * classes * MyClass * * methods * MyClass.method2 * * functions * MyClass.method2.nestedFunction1 * MyClass.method2.nestedFunction2 * function1 * function1.nestedFunction3 * function2 * function2.nestedFunction4 * function2.nestedFunction5 * * * Note that MyClass is shown both as a class and as a function (the parser * discovers it actually is a class only later on). This isn't really easy to * fix because a JavaScript function is only a class if it happen to be used as * one, for example it has prototypes. */ function MyClass() { } MyClass.prototype.method2 = function() { // these functions have improper scope function nestedFunction1() { } function nestedFunction2() { } }; // following work fine, just here as a reference function function1() { function nestedFunction3() { } }; function2 = function() { function nestedFunction4() { } function nestedFunction5() { } }; geany-2.0/tests/ctags/bug877956.f90.tags0000644000175000017500000000015514514252267014417 00000000000000c2Ì16384ÎtestÖ0 variable: test :: c2 cm1Ì16384ÎtestÖ0 variable: test :: cm1 testÌ2048Ö0 struct: test geany-2.0/tests/ctags/cython_sample.pyx.tags0000644000175000017500000000115414514252267016217 00000000000000CDefClassÌ1Ö0 class: CDefClass StdClassÌ1Ö0 class: StdClass __init__Ì128Í(self)ÎCDefClassÖ0 method: CDefClass :: __init__(self) c_methodÌ128Í(self, int i)ÎCDefClassÖ0 method: CDefClass :: c_method(self, int i) identityÌ16Í(x)Ö0 function: identity(x) int2stringÌ16Í(int i)Ö0 function: int2string(int i) int_identityÌ16Í(int i)Ö0 function: int_identity(int i) python_varÌ16384Ö0 variable: python_var return_meÌ128Í(self)ÎStdClassÖ0 method: StdClass :: return_me(self) standard_methodÌ128Í(self,i)ÎCDefClassÖ0 method: CDefClass :: standard_method(self,i) stdObjÌ16384Ö0 variable: stdObj geany-2.0/tests/ctags/css-namespace-selectors.css.tags0000644000175000017500000000012714514252267020044 00000000000000*|divÌ2048Ö0 struct: *|div svg|aÌ2048Ö0 struct: svg|a |aÌ2048Ö0 struct: |a geany-2.0/tests/ctags/countall.sql0000644000175000017500000000301114514252267014207 00000000000000rem ----------------------------------------------------------------------- rem URL: http://www.orafaq.com/scripts/plsql/countall.txt rem Filename: countall.sql rem Purpose: Count the number of rows for ALL tables in current schema rem using PL/SQL rem Date: 15-Apr-2000 rem Author: Eberhardt, Roberto (Bolton) (reberhar@husky.ca) rem ----------------------------------------------------------------------- set serveroutput on size 1000000 DECLARE t_c1_tname user_tables.table_name%TYPE; t_command varchar2(200); t_cid integer; t_total_records number(10); stat integer; row_count integer; t_limit integer := 0; -- Only show tables with more rows cursor c1 is select table_name from user_tables order by table_name; BEGIN t_limit := 0; open c1; loop fetch c1 into t_c1_tname; exit when c1%NOTFOUND; t_command := 'SELECT COUNT(0) FROM '||t_c1_tname; t_cid := DBMS_SQL.OPEN_CURSOR; DBMS_SQL.PARSE(t_cid,t_command,dbms_sql.native); DBMS_SQL.DEFINE_COLUMN(t_cid,1,t_total_records); stat := DBMS_SQL.EXECUTE(t_cid); row_count := DBMS_SQL.FETCH_ROWS(t_cid); DBMS_SQL.COLUMN_VALUE(t_cid,1,t_total_records); if t_total_records > t_limit then DBMS_OUTPUT.PUT_LINE(rpad(t_c1_tname,55,' ')|| to_char(t_total_records,'99999999')||' record(s)'); end if; DBMS_SQL.CLOSE_CURSOR(t_cid); end loop; close c1; END; / geany-2.0/tests/ctags/keyword_const.cs0000644000175000017500000000100114514252267015063 00000000000000// const_keyword.cs // Constants using System; public class ConstTest { class MyClass { public int x; public int y; public const int c1 = 5; public const int c2 = c1 + 5; public MyClass(int p1, int p2) { x = p1; y = p2; } } public static void Main() { MyClass mC = new MyClass(11, 22); Console.WriteLine("x = {0}, y = {1}", mC.x, mC.y); Console.WriteLine("c1 = {0}, c2 = {1}", MyClass.c1, MyClass.c2 ); } } geany-2.0/tests/ctags/simple.d0000644000175000017500000000162014514252267013307 00000000000000module test.simple; import std.stdio; alias AliasInt = int; struct Struct { union Union { bool quxx; int qar; } } enum Enum : int { foo, bar, } interface Interface { public AliasInt bar(); } class Class : Interface { private AliasInt _bar; public this(AliasInt x) { this._bar = x; } public AliasInt bar() { return this._bar; } protected: auto tfun(T)(T v) { return v; } } public { int missing; // FIXME - parse protection blocks } template Template(alias a, T...) { alias TemplateAlias = a!T; } Object obj; private: int i; /+ int error; +/ static if (is(typeof(__traits(getMember, a, name)) == function)) T conditional; static assert( num < TL.length, "Name '"~name~"' is not found"); __gshared int globalVar; void main(string[] args) { auto foo = new Class(1337); alias string AliasString; AliasString baz = "Hello, World!"; writefln("%s", foo.bar()); } geany-2.0/tests/ctags/68hc11.asm0000644000175000017500000000075214514252267013272 00000000000000INTERRUPTS: ; PORTD EQU $1008 ; SP EQU $20 ; TRAPP FCB CR,LF FCB CR,LF FCC ' ******** ILLEGAL OPCODE TRAP !!! ********' FCB CR,LF FCB 0 PROMPT FCB CR,LF FCC ' 68Mon V1.2 (C) 1992 Keith Vasilakes' FCB CR,LF FCB 0 COLD LDS #STACK LDAA #$20 ; http://www.mekatronix.com/downloads/docs/as11_man.pdf sym1 EQU 1 sym2: EQU 2 sym3: sym4: bne sym3 geany-2.0/tests/ctags/indexer.cs.tags0000644000175000017500000000034714514252267014600 00000000000000IndexerClassÌ1Ö0 class: IndexerClass MainÌ128Í()ÎMainClassÖ0Ïpublic void method: public void MainClass :: Main() MainClassÌ1Ö0 class: MainClass myArrayÌ8ÎIndexerClassÖ0Ïint[] field: int[] IndexerClass :: myArray geany-2.0/tests/ctags/sql_single_quote.sql.tags0000644000175000017500000000011014514252267016675 00000000000000p1Ì256Ö0 namespace: p1 p2Ì256Ö0 namespace: p2 p3Ì256Ö0 namespace: p3 geany-2.0/tests/ctags/line_directives.c.tags0000644000175000017500000000014014514252267016116 00000000000000aÌ16384Ö0Ïint variable: int a bÌ16384Ö0Ïint variable: int b cÌ16384Ö0Ïint variable: int c geany-2.0/tests/ctags/css-singlequote-in-comment-issue2.css0000644000175000017500000000002514514252267020762 00000000000000a{x:0;/*'*/} b{y:0;} geany-2.0/tests/ctags/misc_types.f0000644000175000017500000000104114514252267014174 00000000000000! Provided by Brian Helsinki, 7 March 2003 ! cexternal ! cglobal ! pexternal ! pglobal ! inline ! virtual ! volatile ! pascal program specs VIRTUAL M(10,10), Y(100) VOLATILE V, Z, MAT, /INI/ EXTERNAL ABS ! variations of external and global CEXTERNAL ABS1 ! not supported CGLOBAL ABS2 ! not supported PEXTERNAL ABS3 ! not supported $IF DEFINED(MAC_DEP) PASCAL EXTERNAL ABS3_var2 ! not supported $ENDIF PGLOBAL ABS4 INTEGER INFOOBAR INLINE (INFOOBAR=00000) ! not supported INTEGER M(5) DATA M/5*0/ CALL INFOOBAR(5,4) END geany-2.0/tests/ctags/bug1938565.sql0000644000175000017500000000051414514252267013735 00000000000000CREATE OR REPLACE PACKAGE demo_pkg IS FUNCTION func1_proto( value in varchar ) RETURNS number; FUNCTION func2_proto( value in varchar ) RETURN number; FUNCTION func1( value in varchar ) RETURNS number IS BEGIN RETURN 1; END func1; FUNCTION func2( value in varchar ) RETURN number IS BEGIN RETURN 2; END func2; END demo_pkg; / geany-2.0/tests/ctags/enum.f90.tags0000644000175000017500000000425614514252267014102 00000000000000ConstantsÌ256Ö0 namespace: Constants E_eÌ16384ÎConstantsÖ0 variable: Constants :: E_e Named1Ì2ÎConstantsÖ0 enum: Constants :: Named1 Named2Ì2ÎConstantsÖ0 enum: Constants :: Named2 Named3Ì2ÎConstantsÖ0 enum: Constants :: Named3 Named4Ì2ÎConstantsÖ0 enum: Constants :: Named4 Named5Ì2ÎConstantsÖ0 enum: Constants :: Named5 Named6Ì2ÎConstantsÖ0 enum: Constants :: Named6 Named7Ì2ÎConstantsÖ0 enum: Constants :: Named7 aÌ4Îanon_enum_2Ö0 enumerator: anon_enum_2 :: a anon_enum_1Ì2ÎConstantsÖ1 enum: Constants :: anon_enum_1 flags: 1 anon_enum_2Ì2ÎConstantsÖ1 enum: Constants :: anon_enum_2 flags: 1 bÌ4Îanon_enum_2Ö0 enumerator: anon_enum_2 :: b blackÌ4Îanon_enum_1Ö0 enumerator: anon_enum_1 :: black blueÌ4Îanon_enum_1Ö0 enumerator: anon_enum_1 :: blue bronzeÌ4Îanon_enum_1Ö0 enumerator: anon_enum_1 :: bronze cÌ4Îanon_enum_2Ö0 enumerator: anon_enum_2 :: c goldÌ4Îanon_enum_1Ö0 enumerator: anon_enum_1 :: gold hcÌ16384ÎConstantsÖ0 variable: Constants :: hc lavenderÌ4Îanon_enum_1Ö0 enumerator: anon_enum_1 :: lavender piÌ16384ÎConstantsÖ0 variable: Constants :: pi pinkÌ4Îanon_enum_1Ö0 enumerator: anon_enum_1 :: pink purpleÌ4Îanon_enum_1Ö0 enumerator: anon_enum_1 :: purple redÌ4Îanon_enum_1Ö0 enumerator: anon_enum_1 :: red silverÌ4Îanon_enum_1Ö0 enumerator: anon_enum_1 :: silver x1Ì4ÎNamed1Ö0 enumerator: Named1 :: x1 x2Ì4ÎNamed2Ö0 enumerator: Named2 :: x2 x3Ì4ÎNamed3Ö0 enumerator: Named3 :: x3 x4Ì4ÎNamed4Ö0 enumerator: Named4 :: x4 x5Ì4ÎNamed5Ö0 enumerator: Named5 :: x5 x6Ì4ÎNamed6Ö0 enumerator: Named6 :: x6 x7Ì4ÎNamed7Ö0 enumerator: Named7 :: x7 y1Ì4ÎNamed1Ö0 enumerator: Named1 :: y1 y2Ì4ÎNamed2Ö0 enumerator: Named2 :: y2 y3Ì4ÎNamed3Ö0 enumerator: Named3 :: y3 y4Ì4ÎNamed4Ö0 enumerator: Named4 :: y4 y5Ì4ÎNamed5Ö0 enumerator: Named5 :: y5 y6Ì4ÎNamed6Ö0 enumerator: Named6 :: y6 y7Ì4ÎNamed7Ö0 enumerator: Named7 :: y7 yellowÌ4Îanon_enum_1Ö0 enumerator: anon_enum_1 :: yellow z1Ì4ÎNamed1Ö0 enumerator: Named1 :: z1 z2Ì4ÎNamed2Ö0 enumerator: Named2 :: z2 z3Ì4ÎNamed3Ö0 enumerator: Named3 :: z3 z4Ì4ÎNamed4Ö0 enumerator: Named4 :: z4 z5Ì4ÎNamed5Ö0 enumerator: Named5 :: z5 z6Ì4ÎNamed6Ö0 enumerator: Named6 :: z6 z7Ì4ÎNamed7Ö0 enumerator: Named7 :: z7 geany-2.0/tests/ctags/lanus.for.tags0000644000175000017500000000025214514252267014440 00000000000000FAC010Ì16384Ö0 variable: FAC010 FEC010Ì16384Ö0 variable: FEC010 PER010Ì16384Ö0 variable: PER010 REM010Ì16384Ö0 variable: REM010 URE010Ì16384Ö0 variable: URE010 geany-2.0/tests/ctags/keyword_out.cs.tags0000644000175000017500000000032014514252267015504 00000000000000MainÌ128Í()ÎMyClassÖ0Ïpublic void method: public void MyClass :: Main() MyClassÌ1Ö0 class: MyClass TestOutÌ128Í(out char i)ÎMyClassÖ0Ïpublic int method: public int MyClass :: TestOut(out char i) geany-2.0/tests/ctags/bug1924919.cpp0000644000175000017500000000013314514252267013713 00000000000000#include namespace mud { std::string MajorVersion; std::string MinorVersion; }; geany-2.0/tests/ctags/simple.vala0000644000175000017500000000145614514252267014016 00000000000000class Demo.HelloWorld : GLib.Object { /* atomic types */ unichar c = 'u'; float percentile = 0.75f; const double MU_BOHR = 927.400915E-26; bool the_box_has_crashed = false; /* defining a struct */ struct Vector { public double x; public double y; public double z; } /* defining an enum */ enum WindowType { TOPLEVEL, POPUP } public signal void sig_1(int a); private int _age = 32; // underscore prefix to avoid name clash with property /* Property */ public int age { get { return _age; } set { _age = value; } } public static int main(string[] args) { stdout.printf("Hello, World\n"); return 0; } } public interface ITest : GLib.Object { public abstract int data_1 { get; set; } public abstract void method_1(); } namespace NameSpaceName { class Foo {} }geany-2.0/tests/ctags/readlob.sql.tags0000644000175000017500000000062614514252267014744 00000000000000b_fileÌ8Îlob_tableÖ0 field: lob_table :: b_file b_lobÌ8Îlob_tableÖ0 field: lob_table :: b_lob c_lobÌ8Îlob_tableÖ0 field: lob_table :: c_lob charbufÌ16384Ö0 variable: charbuf clob_locatorÌ16384Ö0 variable: clob_locator idÌ8Îlob_tableÖ0 field: lob_table :: id lob_tableÌ1Ö0 class: lob_table read_amountÌ16384Ö0 variable: read_amount read_offsetÌ16384Ö0 variable: read_offset geany-2.0/tests/ctags/1880687.js0000644000175000017500000000620314514252267013056 00000000000000 // All these examples contain various forms of statements // with missing semicolons. Each of these are valid and must // be accommodated. // // After running ctags: ctags -f tags 1880687.js // The following tags should be generated: // functions // a // aa // aa_sub1 [aa] // aa_sub2 [aa] // b // baz [f] // c // d // e // f // g // h // i // j // k // l // m // n // o // p // q // r // s // t // u // v // w // w_sub1 [w] // w_sub2 [w] // x // x_sub1 [x] // x_sub2 [x] // y // y_sub1 [y] // y_sub2 [y] // z // z_sub1 [z] // z_sub2 [z] // classes // MyClass // methods // MyClass_sub1 [MyClass] // MyClass_sub2 [MyClass] function a(flag){ if(flag) test(1); else test(2) } function b(){ var b= 33; } function c(flag){ if(flag) test(1); } function d(){ var b= 33; } function e(flag){ if(flag) test(1) } function f(){ var b= 33; if (foo) bar(); else test(2); function baz() { } } function g(flag){ if(flag) { test(1) } } function h(){ var b= 33; } function i(flag){ if(flag) { test(1); } } function j(){ var b= 33; } function k(flag){ if(flag) { test(1); } else flag = false; } function l(){ var b= 33; } function m(flag){ if(flag) { test(1); } else { flag = false; } } function n(){ var b= 33; } if (1) l(); function o(){ var b= 33; } if (1){ l(); } function p(){ var b= 33; } if (1){ l(); } else l(); function q(){ var b= 33; } function r(flag){ if (flag) { value = 33 } } function s(){ var b= 33; } function t(flag){ if (flag) { b= new Object() } } function u(flag){ if (flag) { b= ({}) } } function v(flag){ if (flag) { b= {} } } function w(){ function w_sub1(x){ if (! x) x = {foo:bar}; var dummy1, dummy2; } function w_sub2(){ } } MyClass = { MyClass_sub1: function(x){ if (! x) x = { }; var dummy3, dummy4; }, MyClass_sub2: function(x){ var dummy5 = 42; } }; function x(){ function x_sub1(){ while (1) x_sub2() } function x_sub2(){ } } function y(){ function y_sub1(){ while (1) { y_sub2() } } function y_sub2(){ } } function z(){ function z_sub1(){ do { z_sub2() } while (0) } function z_sub2(){ } } function aa(){ function aa_sub1(){ do aa_sub2() while (0) } function aa_sub2(){ } } geany-2.0/tests/ctags/char-selector.f90.tags0000644000175000017500000000076114514252267015666 00000000000000MXDDIÌ16384ÎOUT_RD5Ö0 variable: OUT_RD5 :: MXDDI OUT_RD5Ì256Ö0 namespace: OUT_RD5 fpshapeÌ16384ÎOUT_RD5Ö0 variable: OUT_RD5 :: fpshape fpshape2Ì16384ÎOUT_RD5Ö0 variable: OUT_RD5 :: fpshape2 lastÌ16384ÎOUT_RD5Ö0 variable: OUT_RD5 :: last listÌ16384ÎOUT_RD5Ö0 variable: OUT_RD5 :: list noutÌ16384ÎOUT_RD5Ö0 variable: OUT_RD5 :: nout tempÌ16384ÎOUT_RD5Ö0 variable: OUT_RD5 :: temp titlesÌ16384ÎOUT_RD5Ö0 variable: OUT_RD5 :: titles unitsÌ16384ÎOUT_RD5Ö0 variable: OUT_RD5 :: units geany-2.0/tests/ctags/css-attribute-selectors.css0000644000175000017500000000024214514252267017154 00000000000000 body { color: black; } a[href^="http://"] { color: red; } a[href^="https://"] { color: green; } a[lang~=en] { background-color: light-green; } p { color: gray } geany-2.0/tests/ctags/secondary_fcn_name.js.tags0000644000175000017500000000031414514252267016760 00000000000000D1Ì16Í(a, b)Ö0 function: D1(a, b) D2Ì16Í(a, b)Ö0 function: D2(a, b) D2AÌ16Í(a, b)Ö0 function: D2A(a, b) my_global_var1Ì16384Ö0 variable: my_global_var1 theAddÌ16Í(a, b)Ö0 function: theAdd(a, b) geany-2.0/tests/ctags/signature.cpp.tags0000644000175000017500000000050114514252267015310 00000000000000bÌ16384Ö0Ïchar variable: char b barÌ16Í(char * c,double d[]) constÎBARÖ0Ïchar * function: char * BAR :: bar(char * c,double d[]) const barÌ1024Í(a,b)Ö0Ïint prototype: int bar(a,b) fooÌ16Í(int a,char b)Ö0Ïvoid function: void foo(int a,char b) foobarÌ1024Í(int a,char b)Ö0Ïvoid prototype: void foobar(int a,char b) geany-2.0/tests/ctags/bug852368.cpp.tags0000644000175000017500000000012214514252267014563 00000000000000fooÌ1024Í(std::vector &)Ö0Ïvoid prototype: void foo(std::vector &) geany-2.0/tests/ctags/bug1491666.c0000644000175000017500000000015714514252267013357 00000000000000typedef struct { int x; float y; } my_struct; void main (void) { my_struct var1; my_struct var2; } geany-2.0/tests/ctags/bug1201689.c0000644000175000017500000000167114514252267013353 00000000000000/* Bugs item #1201689, was opened at 2005-05-13 18:18 Message generated for change (Tracker Item Submitted) made by Item Submitter You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=106556&aid=1201689&group_id=6556 Category: None Group: None Status: Open Resolution: None Priority: 5 Submitted By: Scott Ferguson (shf301) Assigned to: Nobody/Anonymous (nobody) Summary: Variable Length Argument Lists in K&R Style not Parsed Initial Comment: A function with a K&R style parameter list that has a variable length argument list will not be added to the tags file. For example create a file, say test.c with the following code */ void test(a, ...) char a; { return; } /* Run ctags test.c. the tags file with only contain the line: a test.c /^char a;$/;" v This occurs with ctags 5.3 and 5.5.4. Variable length argument lists work fine if the function is in ANSI style, void test(char a, ...) will work fine. */ geany-2.0/tests/ctags/vhdl-process.vhd0000644000175000017500000000264414514252267014774 00000000000000-- -- Taken from rtl/riverlib/core/stacktrbuf.vhd of https://github.com/sergeykhbr/riscv_vhdl -- ----------------------------------------------------------------------------- --! @file --! @copyright Copyright 2017 GNSS Sensor Ltd. All right reserved. --! @author Sergey Khabarov - sergeykhbr@gmail.com --! @brief Stack trace buffer on hardware level. ------------------------------------------------------------------------------ library ieee; use ieee.std_logic_1164.all; library commonlib; use commonlib.types_common.all; entity StackTraceBuffer is generic ( abits : integer := 5; dbits : integer := 64 ); port ( i_clk : in std_logic; i_raddr : in std_logic_vector(abits-1 downto 0); o_rdata : out std_logic_vector(dbits-1 downto 0); i_we : in std_logic; i_waddr : in std_logic_vector(abits-1 downto 0); i_wdata : in std_logic_vector(dbits-1 downto 0) ); end; architecture arch_StackTraceBuffer of StackTraceBuffer is type ram_type is array ((2**abits)-1 downto 0) of std_logic_vector (dbits-1 downto 0); signal stackbuf : ram_type; signal raddr : std_logic_vector(abits-1 downto 0); begin -- registers: regs : process(i_clk) begin if rising_edge(i_clk) then if i_we = '1' then stackbuf(conv_integer(i_waddr)) <= i_wdata; end if; raddr <= i_raddr; end if; end process; o_rdata <= stackbuf(conv_integer(raddr)); end; geany-2.0/tests/ctags/debian_432872.f900000644000175000017500000000055414514252267014251 00000000000000! { dg-do compile } ! PR18923 segfault after subroutine name confusion. module FOO contains subroutine FOO ! { dg-error "conflicts with PROCEDURE" } character(len=selected_int_kind(0)) :: C ! { dg-error "data declaration statement" } end subroutine ! { dg-error "Expecting END MODULE statement" } end ! { dg-warning "CONTAINS statement without FUNCTION" }geany-2.0/tests/ctags/geany.nsi0000644000175000017500000003722114514252267013475 00000000000000;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; geany.nsi - this file is part of Geany, a fast and lightweight IDE ; ; Copyright 2007-2012 Enrico Tröger ; Copyright 2007-2012 Nick Treleaven ; ; This program 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; either version 2 of the License, or ; (at your option) any later version. ; ; This program 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, write to the Free Software ; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ; ; ; Installer script for Geany (Windows Installer) ; (Script originally generated by the HM NIS Edit Script Wizard) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Do a Cyclic Redundancy Check to make sure the installer was not corrupted by the download CRCCheck force RequestExecutionLevel highest ; set execution level for Windows Vista ;;;;;;;;;;;;;;;;;;; ; helper defines ; ;;;;;;;;;;;;;;;;;;; !define PRODUCT_NAME "Geany" !define PRODUCT_VERSION "1.35" !define PRODUCT_VERSION_ID "1.35.0.0" !define PRODUCT_PUBLISHER "The Geany developer team" !define PRODUCT_WEB_SITE "https://www.geany.org/" !define PRODUCT_DIR_REGKEY "Software\Geany" !define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" !define PRODUCT_EXE "$INSTDIR\bin\Geany.exe" !define PRODUCT_REGNAME "Geany.ProjectFile" !define PRODUCT_EXT ".geany" !define RESOURCEDIR "geany-${PRODUCT_VERSION}" !define GTK_VERSION 2.24.30 ;;;;;;;;;;;;;;;;;;;;; ; Version resource ; ;;;;;;;;;;;;;;;;;;;;; VIProductVersion "${PRODUCT_VERSION_ID}" VIAddVersionKey "ProductName" "${PRODUCT_NAME}" VIAddVersionKey "FileVersion" "${PRODUCT_VERSION}" VIAddVersionKey "ProductVersion" "${PRODUCT_VERSION}" VIAddVersionKey "LegalCopyright" "Copyright 2005-2018 by the Geany developer team" VIAddVersionKey "FileDescription" "${PRODUCT_NAME} Installer" BrandingText "$(^NAME) installer (NSIS 2.51)" InstallDir "$PROGRAMFILES\Geany" Name "${PRODUCT_NAME} ${PRODUCT_VERSION}" SetCompressor /SOLID lzma ShowInstDetails hide ShowUnInstDetails hide XPStyle on !ifdef INCLUDE_GTK OutFile "geany-${PRODUCT_VERSION}_setup.exe" !else OutFile "geany-${PRODUCT_VERSION}_nogtk_setup.exe" !endif Var Answer Var UserName Var StartmenuFolder Var UNINSTDIR ;;;;;;;;;;;;;;;; ; MUI Settings ; ;;;;;;;;;;;;;;;; !include "MUI2.nsh" ;Reserve files used in .onInit, for faster start-up ReserveFile "${NSISDIR}\Plugins\System.dll" ReserveFile "${NSISDIR}\Plugins\UserInfo.dll" ReserveFile "${NSISDIR}\Plugins\InstallOptions.dll" ReserveFile "${NSISDIR}\Plugins\LangDLL.dll" !define MUI_ABORTWARNING !define MUI_ICON "icons\geany.ico" !define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\modern-uninstall-full.ico" ; Welcome page !insertmacro MUI_PAGE_WELCOME ; License page ;!define MUI_LICENSEPAGE_RADIOBUTTONS !insertmacro MUI_PAGE_LICENSE "${RESOURCEDIR}\Copying.txt" ; Components page !insertmacro MUI_PAGE_COMPONENTS ; Directory page !define MUI_PAGE_CUSTOMFUNCTION_LEAVE OnDirLeave !insertmacro MUI_PAGE_DIRECTORY ; Start menu page !define MUI_STARTMENUPAGE_DEFAULTFOLDER "Geany" !define MUI_STARTMENUPAGE_REGISTRY_ROOT HKLM !define MUI_STARTMENUPAGE_REGISTRY_KEY "${PRODUCT_UNINST_KEY}" !define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "Start Menu Folder" !insertmacro MUI_PAGE_STARTMENU ${PRODUCT_NAME} "$StartmenuFolder" ; Instfiles page !insertmacro MUI_PAGE_INSTFILES ; Finish page !define MUI_FINISHPAGE_SHOWREADME "$INSTDIR\News.txt" !define MUI_FINISHPAGE_SHOWREADME_TEXT "Show Release Notes" !define MUI_FINISHPAGE_SHOWREADME_NOTCHECKED !define MUI_FINISHPAGE_RUN "$INSTDIR\bin\Geany.exe" !define MUI_FINISHPAGE_RUN_NOTCHECKED !insertmacro MUI_PAGE_FINISH !insertmacro MUI_UNPAGE_INSTFILES ; Uninstaller page !insertmacro MUI_LANGUAGE "English" ; Language file ;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Sections and InstTypes ; ;;;;;;;;;;;;;;;;;;;;;;;;;;; InstType "Full" InstType "Minimal" Section "!Program Files" SEC01 SectionIn RO 1 2 SetOverwrite ifnewer SetOutPath "$INSTDIR" File "${RESOURCEDIR}\*.txt" SetOutPath "$INSTDIR\bin" File "${RESOURCEDIR}\bin\Geany.exe" File "${RESOURCEDIR}\bin\*Geany*.dll" # non-GTK dependencies File "gtk\bin\libgcc_s_dw*.dll" File "gtk\bin\libstdc++-*.dll" File "gtk\bin\libwinpthread*.dll" SetOutPath "$INSTDIR\libexec" File /r "${RESOURCEDIR}\libexec\*" SetOutPath "$INSTDIR\data" File "${RESOURCEDIR}\data\GPL-2" File "${RESOURCEDIR}\data\filetype_extensions.conf" File "${RESOURCEDIR}\data\geany.glade" !if ${GTK_VERSION} >= 3 File "${RESOURCEDIR}\data\geany-3.20.css" File "${RESOURCEDIR}\data\geany.css" !else File "${RESOURCEDIR}\data\geany.gtkrc" !endif File "${RESOURCEDIR}\data\snippets.conf" File "${RESOURCEDIR}\data\ui_toolbar.xml" SetOutPath "$INSTDIR\data\filedefs" File /r "${RESOURCEDIR}\data\filedefs\*" SetOutPath "$INSTDIR\data\templates" File /r "${RESOURCEDIR}\data\templates\*" SetOutPath "$INSTDIR\data\colorschemes" File /r "${RESOURCEDIR}\data\colorschemes\*" # Geany color schemes project, don't bail out if they are missing File /nonfatal /r "..\geany-themes\colorschemes\*.conf" SetOutPath "$INSTDIR\share\icons" File /r "${RESOURCEDIR}\share\icons\*" SetOutPath "$INSTDIR" CreateShortCut "$INSTDIR\Geany.lnk" "$INSTDIR\bin\Geany.exe" !insertmacro MUI_STARTMENU_WRITE_BEGIN ${PRODUCT_NAME} CreateDirectory "$SMPROGRAMS\$StartmenuFolder" CreateShortCut "$SMPROGRAMS\$StartmenuFolder\Geany.lnk" "$INSTDIR\bin\Geany.exe" !insertmacro MUI_STARTMENU_WRITE_END ; register the extension .geany ; write information about file type WriteRegStr SHCTX "Software\Classes\${PRODUCT_REGNAME}" "" "${PRODUCT_NAME} Project File" WriteRegStr SHCTX "Software\Classes\${PRODUCT_REGNAME}\DefaultIcon" "" "${PRODUCT_EXE},0" WriteRegStr SHCTX "Software\Classes\${PRODUCT_REGNAME}\Shell\open\command" "" '"${PRODUCT_EXE}" "%1"' ; write information about file extensions WriteRegStr SHCTX "Software\Classes\${PRODUCT_EXT}" "" "${PRODUCT_REGNAME}" ; refresh shell System::Call 'shell32.dll::SHChangeNotify(i, i, i, i) (0x08000000, 0, 0, 0)' SectionEnd Section "Plugins" SEC02 SectionIn 1 SetOverwrite ifnewer SetOutPath "$INSTDIR\lib\geany" File "${RESOURCEDIR}\lib\geany\*.dll" SectionEnd Section "Language Files" SEC03 SectionIn 1 SetOutPath "$INSTDIR\share\locale" File /r "${RESOURCEDIR}\share\locale\*" !ifdef INCLUDE_GTK SetOutPath "$INSTDIR\share\locale" File /r "gtk\share\locale\*" !endif SectionEnd Section "Documentation" SEC04 SectionIn 1 SetOverwrite ifnewer SetOutPath "$INSTDIR\share\doc" File /r "${RESOURCEDIR}\share\doc\*" WriteIniStr "$INSTDIR\Documentation.url" "InternetShortcut" "URL" "$INSTDIR\share\doc\geany\html\index.html" !insertmacro MUI_STARTMENU_WRITE_BEGIN ${PRODUCT_NAME} CreateShortCut "$SMPROGRAMS\$StartmenuFolder\Documentation.lnk" "$INSTDIR\Documentation.url" !insertmacro MUI_STARTMENU_WRITE_END SectionEnd Section "Autocompletion Tags" SEC05 SectionIn 1 SetOverwrite ifnewer SetOutPath "$INSTDIR\data\tags" File /r "${RESOURCEDIR}\data\tags\*" SectionEnd ; Include GTK runtime library but only if desired from command line !ifdef INCLUDE_GTK Section "GTK ${GTK_VERSION} Runtime Environment" SEC06 SectionIn 1 SetOverwrite ifnewer SetOutPath "$INSTDIR" File "gtk\ReadMe.Dependencies.Geany.txt" SetOutPath "$INSTDIR\bin" File /r "gtk\bin\*" SetOutPath "$INSTDIR\etc" File /r "gtk\etc\*" SetOutPath "$INSTDIR\lib" File /r "gtk\lib\*" SetOutPath "$INSTDIR\share" File /r "gtk\share\*" SectionEnd !endif Section "Context Menus" SEC07 SectionIn 1 WriteRegStr HKCR "*\shell\OpenWithGeany" "" "Open with Geany" WriteRegStr HKCR "*\shell\OpenWithGeany" "Icon" "$INSTDIR\bin\geany.exe" WriteRegStr HKCR "*\shell\OpenWithGeany\command" "" '"$INSTDIR\bin\geany.exe" "%1"' SectionEnd Section "Desktop Shortcuts" SEC08 SectionIn 1 CreateShortCut "$DESKTOP\Geany.lnk" "$INSTDIR\bin\Geany.exe" CreateShortCut "$QUICKLAUNCH\Geany.lnk" "$INSTDIR\bin\Geany.exe" SectionEnd ; Development files Section "Development files" SEC09 SetOverwrite ifnewer SetOutPath "$INSTDIR\include" File /r "${RESOURCEDIR}\include\*" SetOutPath "$INSTDIR\lib\pkgconfig" File "${RESOURCEDIR}\lib\pkgconfig\geany.pc" SectionEnd Section -AdditionalIcons SetOutPath $INSTDIR !insertmacro MUI_STARTMENU_WRITE_BEGIN ${PRODUCT_NAME} WriteIniStr "$INSTDIR\Website.url" "InternetShortcut" "URL" "${PRODUCT_WEB_SITE}" CreateShortCut "$SMPROGRAMS\$StartmenuFolder\Website.lnk" "$INSTDIR\Website.url" CreateShortCut "$SMPROGRAMS\$StartmenuFolder\Uninstall.lnk" "$INSTDIR\uninst.exe" !insertmacro MUI_STARTMENU_WRITE_END SectionEnd Section -Post WriteUninstaller "$INSTDIR\uninst.exe" WriteRegStr SHCTX "${PRODUCT_DIR_REGKEY}" Path "$INSTDIR" WriteRegStr SHCTX "${PRODUCT_UNINST_KEY}" "StartMenu" "$SMPROGRAMS\$StartmenuFolder" ${if} $Answer == "yes" ; if user is admin WriteRegStr SHCTX "${PRODUCT_UNINST_KEY}" "DisplayName" "$(^Name)" WriteRegStr SHCTX "${PRODUCT_UNINST_KEY}" "UninstallString" "$INSTDIR\uninst.exe" WriteRegStr SHCTX "${PRODUCT_UNINST_KEY}" "DisplayIcon" "$INSTDIR\bin\Geany.exe" WriteRegStr SHCTX "${PRODUCT_UNINST_KEY}" "DisplayVersion" "${PRODUCT_VERSION}" WriteRegStr SHCTX "${PRODUCT_UNINST_KEY}" "URLInfoAbout" "${PRODUCT_WEB_SITE}" WriteRegStr SHCTX "${PRODUCT_UNINST_KEY}" "URLUpdateInfo" "${PRODUCT_WEB_SITE}" WriteRegStr SHCTX "${PRODUCT_UNINST_KEY}" "Publisher" "${PRODUCT_PUBLISHER}" WriteRegDWORD SHCTX "${PRODUCT_UNINST_KEY}" "NoModify" 0x00000001 WriteRegDWORD SHCTX "${PRODUCT_UNINST_KEY}" "NoRepair" 0x00000001 ${endif} SectionEnd Section Uninstall Delete "$INSTDIR\Website.url" Delete "$INSTDIR\Documentation.url" Delete "$INSTDIR\uninst.exe" Delete "$INSTDIR\News.txt" Delete "$INSTDIR\ReadMe.txt" Delete "$INSTDIR\ReadMe.Dependencies.Geany.txt" Delete "$INSTDIR\Thanks.txt" Delete "$INSTDIR\ToDo.txt" Delete "$INSTDIR\Authors.txt" Delete "$INSTDIR\ChangeLog.txt" Delete "$INSTDIR\Copying.txt" Delete "$INSTDIR\Geany.lnk" ; delete start menu entry ReadRegStr $0 SHCTX "${PRODUCT_UNINST_KEY}" "StartMenu" RMDir /r "$0" Delete "$QUICKLAUNCH\Geany.lnk" Delete "$DESKTOP\Geany.lnk" RMDir /r "$INSTDIR\bin" RMDir /r "$INSTDIR\data" RMDir /r "$INSTDIR\etc" RMDir /r "$INSTDIR\include" RMDir /r "$INSTDIR\lib" RMDir /r "$INSTDIR\libexec" RMDir /r "$INSTDIR\share" RMDir "$INSTDIR" ; remove .geany file extension ReadRegStr $R0 SHCTX "Software\Classes\${PRODUCT_EXT}" "" ${if} $R0 == "${PRODUCT_REGNAME}" DeleteRegKey SHCTX "${PRODUCT_EXT}" DeleteRegKey HKCR "${PRODUCT_EXT}" DeleteRegKey SHCTX "${PRODUCT_REGNAME}" DeleteRegKey HKCR "${PRODUCT_REGNAME}" ${endif} DeleteRegKey HKCR "*\shell\OpenWithGeany" DeleteRegKey SHCTX "${PRODUCT_UNINST_KEY}" DeleteRegKey HKCU "${PRODUCT_UNINST_KEY}" DeleteRegKey SHCTX "${PRODUCT_DIR_REGKEY}" DeleteRegKey HKCU "${PRODUCT_DIR_REGKEY}" SetAutoClose true SectionEnd ;;;;;;;;;;;;;;;;;;;;;;;;; ; Section descriptions ; ;;;;;;;;;;;;;;;;;;;;;;;;; !insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN !insertmacro MUI_DESCRIPTION_TEXT ${SEC01} "Required program files. You cannot skip these files." !insertmacro MUI_DESCRIPTION_TEXT ${SEC02} "Available plugins like 'Version Diff', 'Class Builder' and 'Insert Special Characters'." !insertmacro MUI_DESCRIPTION_TEXT ${SEC03} "Various translations of Geany's interface." !insertmacro MUI_DESCRIPTION_TEXT ${SEC04} "Manual in Text and HTML format." !insertmacro MUI_DESCRIPTION_TEXT ${SEC05} "Symbol lists necessary for auto completion of symbols." !ifdef INCLUDE_GTK !insertmacro MUI_DESCRIPTION_TEXT ${SEC06} "You need these files to run Geany. If you have already installed a GTK Runtime Environment (${GTK_VERSION} or higher), you can skip it." !endif !insertmacro MUI_DESCRIPTION_TEXT ${SEC07} "Add context menu item 'Open With Geany'" !insertmacro MUI_DESCRIPTION_TEXT ${SEC08} "Create shortcuts for Geany on the desktop and in the Quicklaunch Bar" !insertmacro MUI_DESCRIPTION_TEXT ${SEC09} "You need these files only if you want to develop own plugins for Geany. If unsure, you can skip it." !insertmacro MUI_FUNCTION_DESCRIPTION_END ;;;;;;;;;;;;;;;;;;;;; ; helper functions ; ;;;;;;;;;;;;;;;;;;;;; ; (from http://jabref.svn.sourceforge.net/viewvc/jabref/trunk/jabref/src/windows/nsis/setup.nsi) !macro IsUserAdmin Result UName ClearErrors UserInfo::GetName IfErrors Win9x Pop $0 StrCpy ${UName} $0 UserInfo::GetAccountType Pop $1 ${if} $1 == "Admin" StrCpy ${Result} "yes" ${else} StrCpy ${Result} "no" ${endif} Goto done Win9x: StrCpy ${Result} "yes" done: !macroend Function .onInit StrCpy "$StartmenuFolder" "Geany" ; (from http://jabref.svn.sourceforge.net/viewvc/jabref/trunk/jabref/src/windows/nsis/setup.nsi) ; If the user does *not* have administrator privileges, abort StrCpy $Answer "" StrCpy $UserName "" !insertmacro IsUserAdmin $Answer $UserName ; macro from LyXUtils.nsh ${if} $Answer == "yes" SetShellVarContext all ; set that e.g. shortcuts will be created for all users ${else} SetShellVarContext current ; TODO is this really what we want? $PROGRAMFILES is not much better because ; probably the unprivileged user can't write it anyways StrCpy $INSTDIR "$PROFILE\$(^Name)" ${endif} ; prevent running multiple instances of the installer System::Call 'kernel32::CreateMutexA(i 0, i 0, t "geany_installer") i .r1 ?e' Pop $R0 StrCmp $R0 0 +3 MessageBox MB_OK|MB_ICONEXCLAMATION "The installer is already running." /SD IDOK Abort ; warn about a new install over an existing installation ReadRegStr $R0 SHCTX "${PRODUCT_UNINST_KEY}" "UninstallString" StrCmp $R0 "" finish MessageBox MB_YESNO|MB_ICONEXCLAMATION \ "Geany has already been installed. $\nDo you want to remove the previous version before installing $(^Name) ?" \ /SD IDYES IDYES remove IDNO finish remove: ; run the uninstaller ClearErrors ; we read the installation path of the old installation from the Registry ReadRegStr $UNINSTDIR SHCTX "${PRODUCT_DIR_REGKEY}" "Path" IfSilent dosilent nonsilent dosilent: ExecWait '$R0 /S _?=$UNINSTDIR' ;Do not copy the uninstaller to a temp file Goto finish nonsilent: ExecWait '$R0 _?=$UNINSTDIR' ;Do not copy the uninstaller to a temp file finish: FunctionEnd Function un.onUninstSuccess HideWindow MessageBox MB_ICONINFORMATION|MB_OK "$(^Name) was successfully removed from your computer." \ /SD IDOK FunctionEnd Function un.onInit ; If the user does *not* have administrator privileges, abort StrCpy $Answer "" !insertmacro IsUserAdmin $Answer $UserName ${if} $Answer == "yes" SetShellVarContext all ${else} ; check if the Geany has been installed with admin permisions ReadRegStr $0 HKLM "${PRODUCT_UNINST_KEY}" "Publisher" ${if} $0 != "" MessageBox MB_OK|MB_ICONSTOP "You need administrator privileges to uninstall Geany!" \ /SD IDOK Abort ${endif} SetShellVarContext current ${endif} MessageBox MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON2 "Are you sure you want to completely remove $(^Name) and all of its components?" \ /SD IDYES IDYES +2 Abort FunctionEnd Function OnDirLeave ClearErrors SetOutPath "$INSTDIR" ; what about IfError creating $INSTDIR? GetTempFileName $1 "$INSTDIR" ; creates tmp file (or fails) FileOpen $0 "$1" "w" ; error to open? FileWriteByte $0 "0" IfErrors notPossible possible notPossible: RMDir "$INSTDIR" ; removes folder if empty MessageBox MB_OK "The given directory is not writeable. Please choose another one!" /SD IDOK Abort possible: FileClose $0 Delete "$1" FunctionEnd geany-2.0/tests/ctags/bug670433.f900000644000175000017500000000175414514252267013445 00000000000000! Bugs item #670443, was opened at 2003-01-18 22:44 ! You can respond by visiting: ! https://sourceforge.net/tracker/?func=detail&atid=106556&aid=670443&group_id=6556 ! ! Category: None ! Group: None ! Status: Open ! Resolution: None ! Priority: 5 ! Submitted By: Erik Edelmann (fanerier) ! Assigned to: Nobody/Anonymous (nobody) ! Summary: Fortran: Internal procedures causes trouble ! ! Initial Comment: ! If a function in a module has an internal procedure ! (after a CONTAINS-statement), everything in the module ! after the parent function will be skipped. I.e. in the ! attached file, the subroutine 'bar' will not be listed ! in the 'tags' file. Note that this problem arises only ! when the parent procedure is a function, if it is a ! subroutine everything works fine. module foobar contains integer function foo (i) contains real function f(x) end function f end function foo subroutine bar (n) end subroutine bar end module foobar geany-2.0/tests/ctags/Makefile.am0000644000175000017500000002113114514252267013704 00000000000000 dist_check_SCRIPTS = runner.sh NULL = test_sources = \ 1795612.js \ 1850914.js \ 1878155.js \ 1880687.js \ 2023624.js \ 3184782.sql \ 3470609.js \ 3526726.tex \ 68hc11.asm \ actionscript/as-first-token.as \ actionscript/classes.as \ actionscript/const2.as \ actionscript/const.as \ actionscript/method-attributes.as \ actionscript/packages.as \ actionscript/sampler.as \ ada-adb.adb \ ada-ads.ads \ ada-expression-function.adb \ ada-expression-function-generic.adb \ ada-overriding.ads \ ada-package-generic.ads \ ada-task.adb \ angle_bracket.cpp \ anonymous_functions.php \ arraylist.js \ array_ref_and_out.cs \ array_spec.f90 \ array-spec.f90 \ attributes.cs \ auto.f \ backslashes.c \ bit_field.c \ block.f90 \ bracematch.js \ bug1020715.cpp \ bug1020715.c \ bug1086609.c \ bug1093123.cpp \ bug1111214-j-chan.v \ bug1111214.v \ bug1201689.c \ bug1447756.java \ bug1458930.c \ bug1466117.c \ bug1491666.c \ bug1515910.cs \ bug1548443.cpp \ bug1563476.cpp \ bug1570779.sql \ bug1575055.cpp \ bug1585745.cpp \ bug1611054.cs \ bug1691412.java \ bug1742588.rb \ bug1743330.v \ bug1764143.h \ bug1764148.py \ bug1770479.cpp \ bug1773926.cpp \ bug1777344.java \ bug1799340.cpp \ bug1799343-1.cpp \ bug1799343-2.cpp \ bug1800065.cs \ bug1809024.py \ bug1830343.cs \ bug1830344.cs \ bug1856363.py \ bug1906062.py \ bug1907083.cpp \ bug1924919.cpp \ bug1938565.sql \ bug1944150.sql \ bug1950327.js \ bug1988026.py \ bug1988027.py \ bug1988130.py \ bug2049723.java \ bug2075402.py \ bug2117073.java \ bug2374109.vhd \ bug2411878.cs \ bug2747828.v \ bug2777310.js \ bug2781264.rb \ bug2886870.tex \ bug2888482.js \ bug3036476.js \ bug3168705.py \ bug3571233.js \ bug507864.c \ bug538629.asm \ bug556645.c \ bug556646.c \ bug565813.f90 \ bug612019.pas \ bug612621.pl \ bug620288.f \ bug639639.h \ bug639644.hpp \ bug665086.cpp \ bug670433.f90 \ bug699171.py \ bug722501.sql \ bug726712.f90 \ bug726875.f90 \ bug734933.f90 \ bug762027.v \ bug814263.java \ bug823000.sql \ bug842077.pl \ bug849591.cpp \ bug852368.cpp \ bug858165.f90 \ bug872494.cpp \ bug877956.f90 \ bug960316.v \ bug961001.v \ byte.f \ c-digraphs.c \ c-trigraphs.c \ case_sensitivity.php \ char-selector.f90 \ classes.php \ cobol/helloworld.cbl \ cobol/helloworld2.cbl \ cobol/levels.cbl \ cobol/quoted-program-id.cbl \ cobol/simple.cbl \ common.f \ complex-return.js \ continuation.f90 \ continuation.mak \ countall.sql \ cpp_destructor.cpp \ css-at-rules.css \ css-at-supports.css \ css-attribute-selectors.css \ css-comma-no-space.css \ css-namespace-selectors.css \ css-pseudo-classes.css \ css-simple.css \ css-singlequote-in-comment-issue2.css \ css-tag-types.css \ css-trivial.css \ cython_sample.pyx \ cython_sample2.pyx \ cxx11enum.cpp \ cxx11-final.cpp \ cxx11-noexcept.cpp \ cxx11-override.cpp \ cxx11-raw-strings.cpp \ cxx14-combined.cpp \ db-trig.sql \ debian_432872.f90 \ directives.c \ dopbl2.f \ dotted-names.json \ enum.c \ enum.f90 \ enum.java \ enumerators.f90 \ events.cs \ extern_variable.h \ forall_module.f90 \ format.pl \ fortran_associate.f90 \ fortran_line_continuation.f90 \ func_typedef.h \ gdscript-inner-class.gd \ gdscript-modifiers.gd \ gdscript-no-implicit-class.gd \ geany.nsi \ general.cs \ hex2dec.sql \ implied_program.f \ indexer.cs \ infinite_loop.java \ ingres_procedures.sql \ initialization.f90 \ interface_indexers.cs \ interface_properties.cs \ interfaces.f90 \ internal.cs \ intro_orig.tex \ intro.tex \ invalid_name.f90 \ java_enum.java \ js-broken-strings.js \ js-class-related-unterminated.js \ js-const.js \ js-implicit-semicolons.js \ js-let.js \ js-scope.js \ js-signature.js \ js-string-continuation.js \ js-sub-block-scope.js \ js-unknown-construct-nesting.js \ julia-corner_cases.jl \ jsFunc_tutorial.js \ keyword_abstract.cs \ keyword_catch_try.cs \ keyword_class.cs \ keyword_const.cs \ keyword_delegate.cs \ keyword_enum.cs \ keyword_event.cs \ keyword_explicit.cs \ keyword_extern.cs \ keyword_implicit.cs \ keyword_interface.cs \ keyword_namespace.cs \ keyword_names.f90 \ keyword_out.cs \ keyword_override.cs \ keyword_params.cs \ keyword_private.cs \ keyword_protected.cs \ keyword_public.cs \ keyword_sealed.cs \ keyword_static.cs \ keyword_struct.cs \ keyword_virtual.cs \ keyword_volatile.cs \ labels.sql \ lanus.for \ line_directives.c \ local.c \ macros.c \ make-comment-in-rule.mak \ make-gnumake-pattern-rules.mak \ make-multi-target.mak \ make-parentheses.mak \ make-target-with-parentheses.mak \ make-variable-on-cmdline.mak \ masm.asm \ matlab_backtracking.m \ matlab_test.m \ maze.erl \ members.f90 \ misc_types.f90 \ misc_types.f \ mode.php \ moniker.x68.asm \ namelist.f \ namespace.cpp \ namespaces2.php \ namespaces.php \ no_terminator.js \ non-ascii-ident1.php \ numlib.f90 \ objectivec_implementation.mm \ objectivec_interface.mm \ objectivec_property.mm \ objectivec_protocol.mm \ Package.pm \ php5_5_class_kw.php \ parenthesis-rvalue.js \ preprocessor.f90 \ procedure_pointer_module.f90 \ procpoint.f90 \ property.cs \ prototype.h \ pure_elem.f95 \ py_constructor_arglist.py \ py-skipped-string.py \ python-anonymous-nestlevel_ctags-bug-356.py \ python-comments.py \ qualified_types.f90 \ random.sql \ readlob.sql \ readlong.sql \ recursive.f95 \ refcurs.sql \ regexp.js \ return-hint.zep \ return-types.go \ ruby-block-call.rb \ ruby-doc.rb \ ruby-namespaced-class.rb \ ruby-scope-after-anonymous-class.rb \ ruby-sf-bug-364.rb \ rules.t2t \ sample.t2t \ secondary_fcn_name.js \ semicolon.f90 \ shebang.js \ signature.cpp \ simple.abc \ simple.asciidoc \ simple.au3 \ simple.bas \ simple.bat \ simple.clj \ simple.conf \ simple.d \ simple.diff \ simple.docbook \ simple.hs \ simple.hx \ simple.html \ simple.inp \ simple.js \ simple.json \ simple.ksh \ simple.lisp \ simple.lua \ simple.mak \ simple.md \ simple.php \ simple.pl \ simple.ps1 \ simple.py \ simple.rb \ simple.rst \ simple.sh \ simple.tcl \ simple.ts \ simple.vala \ simple.zep \ size_t_wchar_t_alias.d \ size_t_wchar_t_typedef.c \ spurious_label_tags.c \ sql_single_quote.sql \ square_parens.f90 \ state_machine.v \ static_array.c \ stdcall.f \ strings.php \ strings.rb \ structure.f \ tabindent.py \ test.erl \ test.go \ test.py \ test_input.rs \ test_input2.rs \ titles.t2t \ traffic_signal.v \ traits.php \ ui5.controller.js \ union.f \ value.f \ var-and-return-type.cpp \ vhdl-component.vhd \ vhdl-local.vhd \ vhdl-port.vhd \ vhdl-process.vhd \ vhdl-type.vhd \ whitespaces.php \ $(NULL) test_results = $(test_sources:=.tags) TEST_EXTENSIONS = .tags TAGS_LOG_COMPILER = $(srcdir)/runner.sh AM_TAGS_LOG_FLAGS = $(top_builddir)/src/geany$(EXEEXT) AM_TESTS_ENVIRONMENT = top_srcdir=$(top_srcdir) top_builddir=$(top_builddir) TESTS = $(test_results) EXTRA_DIST = $(test_sources) $(test_results) # check processing order of files on the command line check_processing_order_sources = \ process_order.c.tags process_order_1.h process_order_2.h EXTRA_DIST += $(check_processing_order_sources) .PHONY: check-processing-order check-processing-order: $(check_processing_order_sources) $(AM_TESTS_ENVIRONMENT) \ $(srcdir)/runner.sh $(top_builddir)/src/geany$(EXEEXT) --result $(check_processing_order_sources:%=$(srcdir)/%) check-local: check-processing-order geany-2.0/tests/ctags/arraylist.js.tags0000644000175000017500000000045614514252267015164 00000000000000aÌ16384Ö0 variable: a bÌ16384Ö0 variable: b barÌ64Îclass.test1Ö0 member: class.test1 :: bar cÌ16384Ö0 variable: c classÌ1Í()Ö0 class: class() fooÌ64Îclass.test1Ö0 member: class.test1 :: foo test1Ì1ÎclassÖ0 class: class :: test1 test3Ì128Í()ÎclassÖ0 method: class :: test3() geany-2.0/tests/ctags/py-skipped-string.py.tags0000644000175000017500000000012414514252267016547 00000000000000f1Ì16Í()Ö0 function: f1() f2Ì16Í()Ö0 function: f2() f3Ì16Í()Ö0 function: f3() geany-2.0/tests/ctags/simple.vala.tags0000644000175000017500000000314114514252267014744 00000000000000Demo.HelloWorldÌ1Ö0 class: Demo.HelloWorld FooÌ1ÎNameSpaceNameÖ0 class: NameSpaceName :: Foo ITestÌ32Ö0 interface: ITest MU_BOHRÌ8ÎDemo.HelloWorldÖ0Ïconst double field: const double Demo.HelloWorld :: MU_BOHR NameSpaceNameÌ256Ö0 namespace: NameSpaceName POPUPÌ4ÎDemo.HelloWorld.WindowTypeÖ0 enumerator: Demo.HelloWorld.WindowType :: POPUP TOPLEVELÌ4ÎDemo.HelloWorld.WindowTypeÖ0 enumerator: Demo.HelloWorld.WindowType :: TOPLEVEL VectorÌ2048ÎDemo.HelloWorldÖ0 struct: Demo.HelloWorld :: Vector WindowTypeÌ2ÎDemo.HelloWorldÖ0 enum: Demo.HelloWorld :: WindowType _ageÌ8ÎDemo.HelloWorldÖ0Ïint field: int Demo.HelloWorld :: _age ageÌ8ÎDemo.HelloWorldÖ0Ïint field: int Demo.HelloWorld :: age cÌ8ÎDemo.HelloWorldÖ0Ïunichar field: unichar Demo.HelloWorld :: c data_1Ì8ÎITestÖ0Ïabstract int field: abstract int ITest :: data_1 mainÌ128Í(string[] args)ÎDemo.HelloWorldÖ0Ïpublic int method: public int Demo.HelloWorld :: main(string[] args) method_1Ì128Í()ÎITestÖ0Ïpublic abstract void method: public abstract void ITest :: method_1() percentileÌ8ÎDemo.HelloWorldÖ0Ïfloat field: float Demo.HelloWorld :: percentile sig_1Ì128Í(int a)ÎDemo.HelloWorldÖ0Ïpublic signal void method: public signal void Demo.HelloWorld :: sig_1(int a) the_box_has_crashedÌ8ÎDemo.HelloWorldÖ0Ïbool field: bool Demo.HelloWorld :: the_box_has_crashed xÌ8ÎDemo.HelloWorld.VectorÖ0Ïdouble field: double Demo.HelloWorld.Vector :: x yÌ8ÎDemo.HelloWorld.VectorÖ0Ïdouble field: double Demo.HelloWorld.Vector :: y zÌ8ÎDemo.HelloWorld.VectorÖ0Ïdouble field: double Demo.HelloWorld.Vector :: z geany-2.0/tests/ctags/bug620288.f0000644000175000017500000000446114514252267013275 00000000000000C Bugs item #620288, was opened at 2002-10-08 08:15 C You can respond by visiting: C https://sourceforge.net/tracker/?func=detail&atid=106556&aid=620288&group_id=6556 C C Category: None C Group: None C Status: Open C Resolution: None C Priority: 5 C Submitted By: Nobody/Anonymous (nobody) C Assigned to: Nobody/Anonymous (nobody) C Summary: fortran function definition C C Initial Comment: C C System Information: C -------------- C ctags version: C Exuberant Ctags 5.3.1, Copyright (C) 1996-2002 Darren C Hiebert C Compiled: Sep 12 2002, 10:22:42 C Addresses: , C http://ctags.sourceforge.net C Optional compiled features: +wildcards, +regex C C Unix: C HP-UX B.11.00 A 9000/800 551726527 C -------------- C C Symptoms: C -------------- C I have a fortran file that has a single function. This C function has a C return type of double precision. I type $ctags bar.f . C This produces the expected C tags file. However, tags does not contain the function C definition. C C This does not occur when the same function's return C type has been changed to C a integer or character data return type. C -------------- C C C Examples in which I can repeat the experience with their C respective tags files: C -------------- C C C foo.f C -------------- integer function foo(a) integer a foo = a end C -------------- C C C tags C -------------- C !_TAG_FILE_FORMAT 2 /extended C format; --format=1 will not append ;" to lines/ C !_TAG_FILE_SORTED 1 C /0=unsorted, 1=sorted, 2=foldcase/ C !_TAG_PROGRAM_AUTHOR Darren Hiebert C /dhiebert@users.sourceforge.net/ C !_TAG_PROGRAM_NAME Exuberant Ctags // C !_TAG_PROGRAM_URL C http://ctags.sourceforge.net /official site/ C !_TAG_PROGRAM_VERSION 5.3.1 // C foo foo.f /^ integer function foo(/;" f C -------------- C C C C bar.f C --------------- double precision function bar(a) double precision a bar = a end C -------------- C C tags C --------------- C !_TAG_FILE_FORMAT 2 /extended C format; --format=1 will not append ;" to lines/ C !_TAG_FILE_SORTED 1 C /0=unsorted, 1=sorted, 2=foldcase/ C !_TAG_PROGRAM_AUTHOR Darren Hiebert C /dhiebert@users.sourceforge.net/ C !_TAG_PROGRAM_NAME Exuberant Ctags // C !_TAG_PROGRAM_URL C http://ctags.sourceforge.net /official site/ C !_TAG_PROGRAM_VERSION 5.3.1 // C --------------- geany-2.0/tests/ctags/fortran_associate.f900000644000175000017500000000047614514252267015707 00000000000000module with_associate real :: a contains function do_stuff(a) result(c) real, intent(in) :: a associate (b => a) c = b end associate end function do_stuff subroutine do_other_stuff(a) real, intent(in out) :: a a = 2 * a end subroutine do_other_stuff end module with_associate geany-2.0/tests/ctags/bug3036476.js0000644000175000017500000000060514514252267013543 00000000000000/* * "Lowercase "object" isn't a keyword" * * ctags -f - bug3036476.js should output: * * variables: * container * * functions: * container.object * container.object.method1 * container.object.method2 */ var container = {}; container.object = function() {} container.object.method1 = function() {} container.object.method2 = function() {} geany-2.0/tests/ctags/secondary_fcn_name.js0000644000175000017500000000144014514252267016024 00000000000000/* * ctags should return the following for parsing this file using: * ctags -f - test.js * functions * D1 * D2 * D2A * theAdd * variables * my_global_var1 */ function D1(a, b) { var my_local_var1 = 'local'; return a+b; } alert(D1(1,2)); // produces 3 // Example D2 var D2=function(a, b) { return a+b; } alert(D2(1,2)); // produces 3 var my_global_var1 = 'global'; // Example D2A // Tags should be generated for both: // D2A // theAdd var D2A=function theAdd(a, b) { return a+b; } alert(D2A(1,2)); // produces 3 alert(theAdd(1,2)); // also produces 3 geany-2.0/tests/ctags/ruby-doc.rb.tags0000644000175000017500000000016414514252267014661 00000000000000f0Ì128Í()Ö0 method: f0() f1Ì128Í()Ö0 method: f1() f2Ì128Í()Ö0 method: f2() f3Ì128Í()Ö0 method: f3() geany-2.0/tests/ctags/test_input2.rs.tags0000644000175000017500000000242114514252267015434 00000000000000SomeLongStructNameÌ1Ö0 class: SomeLongStructName SomeLongStructNameÌ2048Ö0 struct: SomeLongStructName SomeStructÌ2048ÎfruitÖ0 struct: fruit :: SomeStruct another_functionÌ16Í(a:isize,b:isize,c:isize)->isizeÎvegÖ0 function: veg :: another_function(a:isize,b:isize,c:isize)->isize baazÌ128Í()ÎSomeLongStructNameÖ0 method: SomeLongStructName :: baaz() blue_valueÌ8Îfruit::SomeStructÖ0 field: fruit::SomeStruct :: blue_value chalkÌ16Í()ÎmineralÖ0 function: mineral :: chalk() foo_bar_test_funcÌ16Í(apples:fruit::SomeStruct,(oranges,lemon):(isize,isize))->isizeÖ0 function: foo_bar_test_func(apples:fruit::SomeStruct,(oranges,lemon):(isize,isize))->isize foooÌ128Í()ÎSomeLongStructNameÖ0 method: SomeLongStructName :: fooo() free_funcÌ16Í()Ö0 function: free_func() fruitÌ256Ö0 namespace: fruit graniteÌ16Í()ÎmineralÖ0 function: mineral :: granite() green_valueÌ8Îfruit::SomeStructÖ0 field: fruit::SomeStruct :: green_value limestoneÌ16Í()ÎmineralÖ0 function: mineral :: limestone() mainÌ16Í()Ö0 function: main() mineralÌ256Ö0 namespace: mineral not_hashbangÌ16Í()Ö0 function: not_hashbang() red_valueÌ8Îfruit::SomeStructÖ0 field: fruit::SomeStruct :: red_value vÌ8ÎSomeLongStructNameÖ0 field: SomeLongStructName :: v vegÌ256Ö0 namespace: veg geany-2.0/tests/ctags/ingres_procedures.sql0000644000175000017500000000272314514252267016121 00000000000000CREATE PROCEDURE db0001 (short_name varchar(12) not null) BEGIN END; PROCEDURE db0002 (short_name varchar(12) not null) = DECLARE x = varchar(12) not null; n = i4 not null; err = varchar(80) not null not default; BEGIN if short_name = '' then err := 'db0001: Pusty short_name!'; raise error 8001 :err; return -1; endif; select :x = bank_sh_name from "cafa". banks_directory_066 where bank_sh_name = :short_name; if iierrornumber != 0 THEN rollback; err := 'db0001: Podczas sprawdzania unikalnosci short_name banku wystapil blad!'; raise error 8001 :err; return -1; endif; n := iirowcount; commit; return n; END; -- OR with AS instead of =: PROCEDURE db0003 (short_name varchar(12) not null) AS DECLARE x = varchar(12) not null; n = i4 not null; err = varchar(80) not null not default; BEGIN if short_name = '' then err := 'db0001: Pusty short_name!'; raise error 8001 :err; return -1; endif; select :x = bank_sh_name from "cafa". banks_directory_066 where bank_sh_name = :short_name; if iierrornumber != 0 THEN rollback; err := 'db0001: Podczas sprawdzania unikalnosci short_name banku wystapil blad!'; raise error 8001 :err; return -1; endif; n := iirowcount; commit; return n; END geany-2.0/tests/ctags/debian_432872.f90.tags0000644000175000017500000000007714514252267015206 00000000000000FOOÌ128ÎFOOÖ0 method: FOO :: FOO FOOÌ256Ö0 namespace: FOO geany-2.0/tests/ctags/union.f.tags0000644000175000017500000000047114514252267014110 00000000000000dateÌ64ÎstartÖ0 member: start :: date dayÌ64ÎstartÖ0 member: start :: day monthÌ64ÎstartÖ0 member: start :: month sdateÌ16384ÎwritedateÖ0 variable: writedate :: sdate startÌ1ÎwritedateÖ0 class: writedate :: start writedateÌ2048Ö0 struct: writedate yearÌ64ÎstartÖ0 member: start :: year geany-2.0/tests/ctags/simple.pl.tags0000644000175000017500000000015514514252267014436 00000000000000AÌ2Ö0 enum: A A::BÌ512Ö0 package: A::B LABELÌ65536Ö0 macro: LABEL MySubÌ16Ö0 function: MySub geany-2.0/tests/ctags/shebang.js.tags0000644000175000017500000000003214514252267014547 00000000000000fÌ16Í()Ö0 function: f() geany-2.0/tests/ctags/css-singlequote-in-comment-issue2.css.tags0000644000175000017500000000005614514252267021723 00000000000000aÌ2048Ö0 struct: a bÌ2048Ö0 struct: b geany-2.0/tests/ctags/simple.php0000644000175000017500000000206114514252267013653 00000000000000// Examples from PHP Language Reference at // http://www.php.net/manual/en/langref.php items[$artnr] += $num; } // Take $num articles of $artnr out of the cart function remove_item ($artnr, $num) { if ($this->items[$artnr] > $num) { $this->items[$artnr] -= $num; return true; } else { return false; } } } geany-2.0/tests/ctags/js-signature.js0000644000175000017500000000101114514252267014614 00000000000000 function f1() { } function f2(arg1, arg2) { } function f3( arg1, // first arg2, // second arg3 // last ) { // ... } function f4(a, b, c) { } function Cls(name) { this.name = name; } Cls.prototype = { get_name: function() { return this.name; }, set_name: function(name) { this.name = name; }, } Cls.prototype.hello = function(tpl) { if (tpl == undefined) tpl = "hello {}"; return tpl.replace ('{}', this.name); } main = function() { c = new Cls("John"); print(c.hello()); } main(); geany-2.0/tests/ctags/bug1201689.c.tags0000644000175000017500000000005214514252267014300 00000000000000testÌ16Í(a,...)Ö0 function: test(a,...) geany-2.0/tests/ctags/ruby-scope-after-anonymous-class.rb.tags0000644000175000017500000000013714514252267021455 00000000000000CÌ1Ö0 class: C barÌ128Í()ÎCÖ0 method: C :: bar() fooÌ64Í()ÎCÖ0 member: C :: foo() geany-2.0/tests/ctags/semicolon.f90.tags0000644000175000017500000000016214514252267015116 00000000000000SEMIÌ256Ö0 namespace: SEMI VAR1Ì16384ÎSEMIÖ0 variable: SEMI :: VAR1 VAR2Ì16384ÎSEMIÖ0 variable: SEMI :: VAR2 geany-2.0/tests/ctags/1850914.js.tags0000644000175000017500000000033214514252267013776 00000000000000objLiteralMethodÌ128Í()ÎobjectLiteralÖ0 method: objectLiteral :: objLiteralMethod() objLiteralPropertyÌ64ÎobjectLiteralÖ0 member: objectLiteral :: objLiteralProperty objectLiteralÌ1Ö0 class: objectLiteral geany-2.0/tests/ctags/cxx11-final.cpp.tags0000644000175000017500000000063614514252267015353 00000000000000BaseÌ1Ö0 class: Base DerivedÌ1Ö0 class: Derived finalÌ16Í()ÎDerivedÖ0Ïvoid function: void Derived :: final() finalÌ1024Í()ÎDerivedÖ0Ïvoid prototype: void Derived :: final() fooÌ16Í()ÎBaseÖ0Ïvoid function: void Base :: foo() fooÌ16Í()ÎDerivedÖ0Ïvoid function: void Derived :: foo() fooÌ1024Í()ÎBaseÖ0Ïvoid prototype: void Base :: foo() fooÌ1024Í()ÎDerivedÖ0Ïvoid prototype: void Derived :: foo() geany-2.0/tests/ctags/auto.f.tags0000644000175000017500000000026414514252267013730 00000000000000AUTO_TESTÌ2048Ö0 struct: AUTO_TEST DÌ16384ÎAUTO_TESTÖ0 variable: AUTO_TEST :: D PÌ16384ÎAUTO_TESTÖ0 variable: AUTO_TEST :: P QÌ16384ÎAUTO_TESTÖ0 variable: AUTO_TEST :: Q geany-2.0/tests/ctags/vhdl-local.vhd.tags0000644000175000017500000000452414514252267015344 00000000000000LÌ16384Îtypes_util.printÖ0 variable: types_util.print :: L LÌ16384Îtypes_util.tostÖ0 variable: types_util.tost :: L SignalFromStringÌ16Îtypes_utilÖ0 function: types_util :: SignalFromString StringToSVectorÌ16Îtypes_utilÖ0 function: types_util :: StringToSVector StringToUVectorÌ16Îtypes_utilÖ0 function: types_util :: StringToUVector SymbolToSVectorÌ16Îtypes_utilÖ0 function: types_util :: SymbolToSVector UnsignedToSignedÌ16Îtypes_utilÖ0 function: types_util :: UnsignedToSigned cÌ16384Îtypes_util.SymbolToSVectorÖ0 variable: types_util.SymbolToSVector :: c iÌ16384Îtypes_util.UnsignedToSignedÖ0 variable: types_util.UnsignedToSigned :: i indexÌ16384Îtypes_util.tostÖ0 variable: types_util.tost :: index nÌ16384Îtypes_util.strlenÖ0 variable: types_util.strlen :: n nÌ16384Îtypes_util.tostÖ0 variable: types_util.tost :: n nibbleÌ4096Îtypes_utilÖ0 typedef: types_util :: nibble nzÌ16384Îtypes_util.tostÖ0 variable: types_util.tost :: nz printÌ16Îtypes_utilÖ0 function: types_util :: print reverse_vectorÌ4096Îtypes_util.tostÖ0 typedef: types_util.tost :: reverse_vector sÌ16384Îtypes_util.tostÖ0 variable: types_util.tost :: s sjÌ16384Îtypes_util.strlenÖ0 variable: types_util.strlen :: sj slenÌ16384Îtypes_util.tostÖ0 variable: types_util.tost :: slen ssÌ16384Îtypes_util.SymbolToSVectorÖ0 variable: types_util.SymbolToSVector :: ss strlenÌ16Îtypes_utilÖ0 function: types_util :: strlen tempÌ16384Îtypes_util.SignalFromStringÖ0 variable: types_util.SignalFromString :: temp tempÌ16384Îtypes_util.StringToSVectorÖ0 variable: types_util.StringToSVector :: temp tempÌ16384Îtypes_util.StringToUVectorÖ0 variable: types_util.StringToUVector :: temp tempÌ16384Îtypes_util.SymbolToSVectorÖ0 variable: types_util.SymbolToSVector :: temp tempÌ16384Îtypes_util.UnsignedToSignedÖ0 variable: types_util.UnsignedToSigned :: temp tmpÌ16384Îtypes_util.tostÖ0 variable: types_util.tost :: tmp todecÌ16Îtypes_utilÖ0 function: types_util :: todec tohexÌ16Îtypes_utilÖ0 function: types_util :: tohex tostÌ16Îtypes_utilÖ0 function: types_util :: tost types_utilÌ256Ö0 namespace: types_util vectorÌ16384Îtypes_util.tostÖ0 variable: types_util.tost :: vector vlenÌ16384Îtypes_util.tostÖ0 variable: types_util.tost :: vlen vvÌ16384Îtypes_util.tostÖ0 variable: types_util.tost :: vv xÌ16384Îtypes_util.tostÖ0 variable: types_util.tost :: x geany-2.0/tests/ctags/js-scope.js.tags0000644000175000017500000000014114514252267014664 00000000000000AÌ1Í()Ö0 class: A() m1Ì128Í()ÎAÖ0 method: A :: m1() m2Ì128Í()ÎAÖ0 method: A :: m2() geany-2.0/tests/ctags/bug1611054.cs.tags0000644000175000017500000000021414514252267014452 00000000000000CÌ1Ö0 class: C aÌ128Í()ÎCÖ0Ïpublic String method: public String C :: a() bÌ128Í()ÎCÖ0Ïpublic void method: public void C :: b() geany-2.0/tests/ctags/keyword_namespace.cs0000644000175000017500000000104714514252267015703 00000000000000// cs_namespace_keyword.cs using System; namespace SomeNameSpace { public class MyClass { public static void Main() { Nested.NestedNameSpaceClass.SayHello(); } } namespace Nested // a nested namespace { public class NestedNameSpaceClass { public static void SayHello() { Console.WriteLine("Hello"); } } } } // namespace can nest multiple levels at once. namespace SomeNameSpace.Nested { public class AlternativeNestedNameSpaceClass { } } geany-2.0/tests/ctags/js-unknown-construct-nesting.js.tags0000644000175000017500000000020214514252267020737 00000000000000aaÌ128Í()ÎoÖ0 method: o :: aa() bbÌ128Í(a)ÎoÖ0 method: o :: bb(a) ccÌ128Í()ÎoÖ0 method: o :: cc() oÌ1Ö0 class: o geany-2.0/tests/ctags/func_typedef.h0000644000175000017500000000006414514252267014476 00000000000000typedef SLIST_HEAD(symlist, symbol_node) symlist_t; geany-2.0/tests/ctags/bug960316.v0000644000175000017500000000250614514252267013312 00000000000000/************************************************************************** **** * test task one * the line below has 53 asteriks *****************************************************/ task pass_task_1; begin end endtask /************************************************************************** **** * test task one * the line below has 54 asteriks ******************************************************/ task fail_task_2; begin end endtask /************************************************************************** **** * test function one * the line below has 53 asteriks *****************************************************/ function pass_func_1; begin end endfunction /************************************************************************** **** * test function two * the line below has 54 asteriks ******************************************************/ function fail_func_2; begin end endfunction /************************************************************************** **** * test function one * the line below has 53 asteriks *****************************************************/ `define pass_define_1 1'b1; /************************************************************************** **** * test function two * the line below has 54 asteriks ******************************************************/ `define fail_define_2 1'b1; geany-2.0/tests/ctags/keyword_params.cs0000644000175000017500000000112014514252267015222 00000000000000// cs_params.cs using System; public class MyClass { public static void UseParams(params int[] list) { for ( int i = 0 ; i < list.Length ; i++ ) Console.WriteLine(list[i]); Console.WriteLine(); } public static void UseParams2(params object[] list) { for ( int i = 0 ; i < list.Length ; i++ ) Console.WriteLine((object)list[i]); Console.WriteLine(); } public static void Main() { UseParams(1, 2, 3); UseParams2(1, 'a', "test"); int[] myarray = new int[3] {10,11,12}; UseParams(myarray); } } geany-2.0/tests/ctags/numlib.f90.tags0000644000175000017500000000036214514252267014416 00000000000000anon_interface_1Ì32Înumerical_librariesÖ1 interface: numerical_libraries :: anon_interface_1 flags: 1 anon_interface_2Ì32Îb2lsfÖ1 interface: b2lsf :: anon_interface_2 flags: 1 numerical_librariesÌ256Ö0 namespace: numerical_libraries geany-2.0/tests/ctags/keyword_struct.cs.tags0000644000175000017500000000046714514252267016235 00000000000000MainÌ128Í()ÎMainClassÖ0Ïpublic void method: public void MainClass :: Main() MainClassÌ1Ö0 class: MainClass PointÌ128Í(int p1, int p2)ÎPointÖ0 method: Point :: Point(int p1, int p2) PointÌ2048Ö0 struct: Point xÌ8ÎPointÖ0Ïint field: int Point :: x yÌ8ÎPointÖ0Ïint field: int Point :: y geany-2.0/tests/ctags/attributes.cs.tags0000644000175000017500000000051714514252267015327 00000000000000AuthorÌ1Ö0 class: Author AuthorÌ128Í(string name)ÎAuthorÖ0 method: Author :: Author(string name) MyDllimportClassÌ1Ö0 class: MyDllimportClass TraceMethodÌ128Í()Ö0Ï[][][][]void method: [][][][]void TraceMethod() nameÌ8ÎAuthorÖ0 field: Author :: name versionÌ8ÎAuthorÖ0Ïdouble field: double Author :: version geany-2.0/tests/ctags/bug734933.f900000644000175000017500000000167014514252267013450 00000000000000 MODULE MDCOMPONENTS USE kindef USE memory IMPLICIT NONE SAVE INTEGER (INT4), PARAMETER :: LIM_COMPONENTS = 1000; INTEGER (INT4) :: NUM_COMPONENTS = 0, NCOMP; TYPE COMPONENT CHARACTER (LEN=30) :: NAME INTEGER (INT4) :: NUM_PART REAL (REAL8), DIMENSION(:), POINTER :: PART_LIST END TYPE TYPE COMPONENT_POINTER TYPE (COMPONENT), POINTER :: P END TYPE TYPE (COMPONENT), POINTER :: COMP TYPE (COMPONENT_POINTER) :: COMP_TMP TYPE (COMPONENT_POINTER), DIMENSION(LIM_COMPONENTS) :: COMPONENTS, COMPONENTS_TMP INTERFACE MEMDEALLOC MODULE PROCEDURE MEMDEALLOC_COMPONENTS_PTR END INTERFACE CONTAINS SUBROUTINE ADD_COMPONENTS NUM_COMPONENTS = NUM_COMPONENTS + 1 CALL MEMALLOC (COMPONENTS(NUM_COMPONENTS)%P, IDALL999) END SUBROUTINE ADD_COMPONENTS END MODULE MDCOMPONENTS geany-2.0/tests/ctags/anonymous_functions.php0000644000175000017500000000055614514252267016511 00000000000000 Added functions rand_string(), smaller(). ------------------------------------------------------------------------------ */ create or replace package random is procedure srand(new_seed in number); procedure get_rand(r OUT number); procedure get_rand_max(r OUT number, n IN number); function rand return number; function rand_max(n IN number) return number; function rand_string(ssiz IN number) return varchar2; function smaller(x IN number, y IN number) return number; pragma restrict_references(rand, WNDS); pragma restrict_references(rand_max, WNDS); pragma restrict_references(random, WNDS, RNPS); pragma restrict_references(rand_string, WNDS); pragma restrict_references(smaller, WNDS); end random; / create or replace package body random is multiplier constant number := 22695477; increment constant number := 1; "2^32" constant number := 2 ** 32; "2^16" constant number := 2 ** 16; "0x7fff" constant number := 32767; Seed number := 1; function smaller(x IN number, y IN number) return number is begin if x <= y then return x; else return y; end if; end smaller; function rand_string(ssiz IN number) return varchar2 is i number; m number; c char; result varchar2(2000) := ''; begin m := smaller(ssiz,2000); for i in 1..m loop c := substr('abcdefghijklmnopqrstuvwxyz0123456789',rand_max(36),1); result := result || c; end loop; return result; end rand_string; procedure srand(new_seed in number) is begin Seed := new_seed; end srand; function rand return number is begin Seed := mod(multiplier * Seed + increment, "2^32"); return bitand(Seed/"2^16", "0x7fff"); end rand; procedure get_rand(r OUT number) is begin r := rand; end get_rand; function rand_max(n IN number) return number is begin return mod(rand, n) + 1; end rand_max; procedure get_rand_max(r OUT number, n IN number) is begin r := rand_max(n); end get_rand_max; begin select userenv('SESSIONID') into Seed from dual; end random; / -- Some examples: select random.rand_max(10) from dual; select random.rand_max(10) from dual; select random.rand_string(20) from dual; select random.rand_string(20) from dual; geany-2.0/tests/ctags/bug538629.asm.tags0000644000175000017500000000004414514252267014565 00000000000000MYMACROÌ65536Ö0 macro: MYMACRO geany-2.0/tests/ctags/keyword_volatile.cs.tags0000644000175000017500000000032514514252267016521 00000000000000MainÌ128Í()ÎTestÖ0Ïpublic void method: public void Test :: Main() TestÌ1Ö0 class: Test TestÌ128Í(int _i)ÎTestÖ0 method: Test :: Test(int _i) iÌ8ÎTestÖ0Ïvolatile int field: volatile int Test :: i geany-2.0/tests/ctags/state_machine.v0000644000175000017500000000214014514252267014642 00000000000000// Taken from http://www.europa.com/~celiac/fsm_samp.html // These are the symbolic names for states parameter [1:0] //synopsys enum state_info S0 = 2'h0, S1 = 2'h1, S2 = 2'h2, S3 = 2'h3; // These are the current state and next state variables reg [1:0] /* synopsys enum state_info */ state; reg [1:0] /* synopsys enum state_info */ next_state; // synopsys state_vector state always @ (state or y or x) begin next_state = state; case (state) // synopsys full_case parallel_case S0: begin if (x) begin next_state = S1; end else begin next_state = S2; end end S1: begin if (y) begin next_state = S2; end else begin next_state = S0; end end S2: begin if (x & y) begin next_state = S3; end else begin next_state = S0; end end S3: begin next_state = S0; end endcase end always @ (posedge clk or posedge reset) begin if (reset) begin state <= S0; end else begin state <= next_state; end end geany-2.0/tests/ctags/3470609.js.tags0000644000175000017500000000106514514252267014003 00000000000000arrayÌ64ÎrootÖ0 member: root :: array decimalÌ64ÎrootÖ0 member: root :: decimal fÌ16Í()Ö0 function: f() idÌ64ÎrootÖ0 member: root :: id methodÌ128Í()ÎrootÖ0 method: root :: method() negÌ64ÎrootÖ0 member: root :: neg parenthesesÌ64ÎrootÖ0 member: root :: parentheses rootÌ1Ö0 class: root stringÌ64ÎrootÖ0 member: root :: string subFunctionÌ128Í()Îroot.subObjectÖ0 method: root.subObject :: subFunction() subObjectÌ1ÎrootÖ0 class: root :: subObject subPropertyÌ64Îroot.subObjectÖ0 member: root.subObject :: subProperty geany-2.0/tests/ctags/no_terminator.js0000644000175000017500000000167514514252267015101 00000000000000function ts_resortTable(lnk) { if (span.getAttribute("sortdir") == 'down') { span.setAttribute('sortdir','up'); } else { span.setAttribute('sortdir','down'); } } function getParent(el, pTagName) { if (el == null) return null; else if (el.nodeType == 1 && el.tagName.toLowerCase() == pTagName.toLowerCase()) // Gecko bug, supposed to be uppercase return el; else return getParent(el.parentNode, pTagName); } function ts_sort_currency(a,b) { aa = ts_getInnerText(a.cells[SORT_COLUMN_INDEX]).replace(/[^0-9.]/g,''); bb = ts_getInnerText(b.cells[SORT_COLUMN_INDEX]).replace(/[^0-9.]/g,''); return parseFloat(aa) - parseFloat(bb); } function checkForUpdate() { if( 1==1 ) { document.write("hello from checkForUpdate
") } return 1; } function checkForUpdate2() { if( 1==1 ) { document.write("hello from checkForUpdate
"); } return 2; } geany-2.0/tests/ctags/bug3036476.js.tags0000644000175000017500000000037114514252267014500 00000000000000containerÌ16384Ö0 variable: container method1Ì16Í()Îcontainer.objectÖ0 function: container.object :: method1() method2Ì16Í()Îcontainer.objectÖ0 function: container.object :: method2() objectÌ16Í()ÎcontainerÖ0 function: container :: object() geany-2.0/tests/ctags/css-at-supports.css.tags0000644000175000017500000000003514514252267016406 00000000000000htmlÌ2048Ö0 struct: html geany-2.0/tests/ctags/simple.clj.tags0000644000175000017500000000061414514252267014573 00000000000000another.nameÌ256Ö0 namespace: another.name app.controllerÌ256Ö0 namespace: app.controller core-function-with-bodyÌ16Îapp.controllerÖ0 function: app.controller :: core-function-with-body empty-fnÌ16Îapp.controllerÖ0 function: app.controller :: empty-fn function-with-bodyÌ16Îapp.controllerÖ0 function: app.controller :: function-with-body xÌ16Îanother.nameÖ0 function: another.name :: x geany-2.0/tests/ctags/bug1799340.cpp0000644000175000017500000000011614514252267013712 00000000000000std::string & f1() {} const std::string & f2() {} std::string const & f3() {} geany-2.0/tests/ctags/simple.ksh.tags0000644000175000017500000000005614514252267014610 00000000000000f1Ì16Ö0 function: f1 f2Ì16Ö0 function: f2 geany-2.0/tests/ctags/classes.php.tags0000644000175000017500000000051114514252267014752 00000000000000BarÌ1Ö0 class: Bar FooÌ1Ö0 class: Foo __constructÌ16Í()ÎBarÖ0 function: Bar :: __construct() __constructÌ16Í($a, $b)ÎFooÖ0 function: Foo :: __construct($a, $b) method1Ì16Í()ÎBarÖ0 function: Bar :: method1() method1Ì16Í($arg)ÎFooÖ0 function: Foo :: method1($arg) method2Ì16Í()ÎFooÖ0 function: Foo :: method2() geany-2.0/tests/ctags/simple.lua0000644000175000017500000000027114514252267013646 00000000000000-- Comment line -- Indented comment line test = {} function test.me_12a(one, two) print"me_12a" end test.i_123 = function (x) print"i_123" end test.me_12a(1,2) test.i_123(1) geany-2.0/tests/ctags/julia-corner_cases.jl0000644000175000017500000002427614514252267015764 00000000000000#= Julia syntax highlighting test. Modified from https://github.com/JuliaEditorSupport/julia-syntax-test-cases This file derives from https://gist.github.com/Wilfred/f1aca44c61ed6e1df603 whose author is [@Wilfred](https://github.com/Wilfred). @Wilfred has put it in the public domain: https://gist.github.com/Wilfred/f1aca44c61ed6e1df603#gistcomment-2948526 Changes from the original are governed by the license of the repository in which this file is found. This file is designed to test various corner cases of Julia syntax highlighting. =# baremodule Mod1 # Nothing here end module Mod2 # Here neither end ## Simple function definitions. # Expected: `function` should be highlighted, as should `foo_bar!`. function foo_bar!(x,y) x + y + 1 end # Expected: `foo_bar!` should be highlighted. foo_bar!(x,y) = x + y # Expected: `foo` should be highlighted. Baz.foo(x) = 1 # Expected: `foo` should be highlighted. foo(x::(Int,)) = 1 # Expected: `foo` should be highlighted. foo(x, y=length(x)) ## Function definitions in namespaces. # Expected: `bar` should be highlighted. function Foo.bar(x, y) x + 1 end ## Function definitions with type variables. # Expected: `elsize` should be highlighted. elsize(::AbstractArray{T}) where {T} = sizeof(T) function elsize(::AbstractArray{T}) where T sizeof(T) end ## Nested brackets in function definitions. # Expected: `cell` should be highlighted. cell(dims::(Integer...)) = Array(Any, convert((Int...), dims)) # TODO: find an example with a nested type expression. ## Macro usage # Expected: `@hello_world!` should be highlighted. @hello_world! foo # Expected: highlight `myfun` @inline myfun() = println("myfun") ## Builtin functions. # Expected: `throw`, `error` and `super` should not be highlighted. There are # too many built-in functions for this to be useful. # https://github.com/JuliaLang/julia/commit/134867c69096fcb52afa5d5a7433892b5127e981 # https://github.com/JuliaLang/julia/pull/7963#issuecomment-52586261 throw(foo) error("foo", bar, "baz") super(Int) ## Strings # Expected: highlight the string. x = "foo \"bar\" baz" # Expected: highlight the whole string. x = "foo bar" # Expected: highlight the whole triple-quoted string. x = """hello "world" foobar""" y = """foo\\""" z = """bar\"""" w = """"bar""" # Expected: highlight `$user` x = "hello $user" # Expected: don't highlight `$user` x = "hello \$user" # Expected: highlight `$val` x = """(a="$val")""" # Expected: treat r as part of the string, so `r"a"` is highlighted. x = r"0.1" # Expected: treat ismx as part of the string, so `r"a"ismx` is highlighted. x = r"a"ismx # Expected: highlight `r"""a "b" c"""` x = r"""a "b" c""" # Expected: treat v as part of the string, so `v"0.1"` is highlighted. x = v"0.1" # Expected: treat b as part of the string, so `b"a"` is highlighted. x = b"a" # Bonus points: # Expected: highlight the interpolation brackets `$(` and `)` x = "hello $(user * user)" # Bonus points: # Expected: highlight regexp metacharacters `[` and `]` x = r"[abc]" # Bonus points: # Expected: highlight escape sequences `\xff` and `\u2200` x = b"DATA\xff\u2200" # Bonus points: # Expected: don't highlight `$user` x = raw"hello $user" ## Characters # Expected: highlight the character. x = 'a' y = '\u0' z = '\U10ffff' w = '\x41' a = ' ' b = '"' c = ''' d = '\'' e = '\\' # Expected: don't highlight, as ' is an operator here, not a character delimiter. a = b' + c' A''' # Bonus points: # Expected: don't highlight the character x = 'way too long so not a character' x = '' ## Comments # Expected: highlight `# foo` # foo # Expected: highlight `#= foo\n bar =#` #= foo bar =# # Expected: highlight `#= #= =# =#` (comments can nest). #= #= =# =# # Expected: highlight `'` as adjoint operator A#==#' (A)#==#' A[1]#==#' ## Type declarations # Expected highlight `Foo` and `Bar` mutable struct Foo x::Bar end # Expected highlight `Foo` and `Bar` struct Foo x::Bar end # Expected: highlight `Foo` and `Bar` abstract type Foo <: Bar end # Expected: don't highlight x or y x <: y ## Type annotations # Expected: highlight `FooBar` f(x::FooBar) = x # Expected: highlight `Int8` function foo() local x::Int8 = 5 x end # Expected: highlight `Point` and `Real` as types function norm(p::Point{<:Real}) sqrt(p.x^2 + p.y^2) end # Expected: highlight `g` as function and `Int8` as type function g(x, y)::Int8 return x * y end # Expected: highlight `T` and `Number` same_type_numeric(x::T, y::T) where {T <: Number} = true same_type_numeric(x::T, y::T) where T = false ## Parametric type declaration # Expected: highlight `Pointy` and `T` abstract type Pointy{T} end # Expected: highlight `Point`, `Pointy` and `T` struct Point{T} <: Pointy{T} x::T y::T end ## Variable declarations # Expected: highlight `x` and `y` global x = "foo, bar = 2", y = 3 # Expected: highlight `x` and `y` global x = foo(a, b), y = 3 # Expected: highlight `y` const y = "hello world" # Expected: highlight `x` and `y` function foo() local x = f(1, 2), y = f(3, 4) x + y end # Expected: highlight `x` and `y` let x = f(1, 2), y = f(3, 4) x + y end ## Colons and end # Expected: highlight `:foo`, `:end` and `:function` :foo x = :foo y = :function z = :end # Expected: highlight index `[end]` differently to block delimiter `end` if foo[end] end # Expected: highlight as index `end` foo[bar:end] # Expected: highlight as index `begin` foo[begin:4] # Expected: don't highlight `:123` x = :123 # Expected: don't highlight `:baz` foo[bar:baz] # Expected: highlight `:baz` foo[:baz] # Expected: highlight both `:baz` foo(:baz,:baz) # Note that `: foo` is currently a valid quoted symbol, this will hopefully # change in 0.4: https://github.com/JuliaLang/julia/issues/5997 # Expected: highlight `:foo` [1 :foo] # Expected: highlight `:end` [1 :end] # Expected: highlight `:two` @eval :one+:two # Expected: don't highlight `:end` but `end` as index [(1+1):end] # Expected: don't highlight `:end` but `end` as index [a[1]:end] # Expected: don't highlight `:foo` for x=1:foo print(x) end ## Range detection # Bonus points: # Expected: don't highlight `:s2` push!(a, s1 :s2) # Bonus points: # Expected: don't highlight `:end` a[begin :end] ## Expression evaluation # Expected: highlight `:` as operator a = :(x = 2) # Expected: highlight `:call` and `:b` as symbols # Debatable: highlight `:+` as operator ex = Expr(:call, :+, a, :b) ## Number highlighting # Expected: highlight all these as numbers x = 123 x = 1.1 x = .5 x = 0x123abcdef x = 0o7 x = 0b1011 x = 2.5e-4 x = 2.5E-4 x = 1e+00 x = 2.5f-4 x = 0x.4p-1 x = 1_000 # Expected: highlight these as numbers or built-ins x = Inf x = NaN # Expected: highlight `123`, not the letter y = 123x y = 123e # Expected: highlight `1e+1` and `1e-1` 1e+1+1e-1 # Expected: highlight `1.` and `.1` 1. +.1 # Note that `1.+1` is currently ambiguous and gives an error # Bonus points: # Expected: don't highlight `..` x = 1..3 # Bonus points: # Debatable: highlight the first two digits, not the following digits # or show an error x = 0o1291 x = 0b1091 # Debatable: highlight `Ï€` as a number or built-in # (note that `Ï€x` is a single symbol, not `Ï€ * x`) x = Ï€ ## List comprehension # Expected: highlight `for` and `if` without the `end` keyword [i for i in 1:5 if i%2==0] ## Broadcasting # Expected: highlight `.+` as operator a.+1 ## Command # Expected: highlight "`echo 1`" c = `echo 1` # Expected: highlight "```echo `hello 1` ```" c = ```echo `hello 1` ``` # Expected: highlight "raw`echo $1`" c = raw`echo $1` ## Non-standard identifiers # Bonus points: # Expected: highlight `var"##"` as a function function var"##"(x) println(x) end # Bonus points: # Expected: highlight `var"%%"` as a function var"%%"(x) = println(x) # Bonus points: # Expected: highlight `$var` as string and `##""` as comment "$var"##"" # Bonus points: # Expected: highlight `$(var")(")` as string interpolation "$(var")(")" # Bonus points: # Expected: highlight `'` as adjoint operator var"##mat"' ## Code folding: for and if in list comprehension # Expected: fold between function and last end function test(x) a = (if x; 0 else 1 end) println(a) end ## Default struct attributes Base.@kwdef struct Test a::Float64 = 1E12 b::Float64 = pi end ## Parametric constructors struct OurRational{T<:Integer} <: Real "Numerator" num::T "Denominator" den::T OurRational{Int8}(num::T, den::T) where T<:Integer = new(convert(Int8, num), convert(Int8, den)) """ Parametric inner constructor """ function OurRational{T}(num::T, den::T) where T<:Integer if num == 0 && den == 0 error("invalid rational: 0//0") end # Bug with short function misidentification of == and => length(num) == 0 length(den) => 0 g = gcd(den, num) num = div(num, g) den = div(den, g) new(num, den) end test::T OurRational{Int64}(num::T, den::T, test::T) where T<:Integer = new(num, den, test) end OurRational{Int16}(num::T, den::T) where T<:Integer = new(num, den) ## Import modules using Module1 using Module2: func1, func2 import Module3 import Module4.func1, Module5, Module6.func2 import Module7: func1, func2 module MyModule using Module8, Module9, Module10 using Module11: func1, func2, func3 end import Base.show, # Base.print as pr, Base.* #using Module12: func1, func2 as alias2, func3 using Module13: func1, # func2 as alias2, func3 #import Module14 as Alias12 ## Function scope module MyModule function func3(a::Int) a end function func4(a::Int) function func5(b::Int) b end func5(a) end end ## Docstring """ This is a test docstring with multiple lines. """ function test_docstring end geany-2.0/tests/ctags/namespaces2.php.tags0000644000175000017500000000074514514252267015527 00000000000000BÌ1ÎBar::BazÖ0 class: Bar::Baz :: B Bar\BazÌ256Ö0 namespace: Bar\Baz CÌ1ÎFooÖ0 class: Foo :: C FooÌ256Ö0 namespace: Foo __constructÌ16Í()ÎBar::Baz::BÖ0 function: Bar::Baz::B :: __construct() __constructÌ16Í()ÎFoo::CÖ0 function: Foo::C :: __construct() aÌ16Í()ÎBar::BazÖ0 function: Bar::Baz :: a() aÌ16Í()ÎFooÖ0 function: Foo :: a() bÌ16Í()ÎFooÖ0 function: Foo :: b() cÌ16Í()ÎBar::Baz::BÖ0 function: Bar::Baz::B :: c() dÌ16Í()ÎFoo::CÖ0 function: Foo::C :: d() geany-2.0/tests/ctags/simple.lua.tags0000644000175000017500000000012614514252267014602 00000000000000i_123Ì16ÎtestÖ0 function: test :: i_123 me_12aÌ16ÎtestÖ0 function: test :: me_12a geany-2.0/tests/ctags/js-const.js.tags0000644000175000017500000000033014514252267014701 00000000000000AÌ65536Ö0 macro: A BÌ65536Ö0 macro: B GroupÌ1Ö0 class: Group XÌ64ÎGroupÖ0 member: Group :: X YÌ64ÎGroupÖ0 member: Group :: Y ZÌ64ÎGroupÖ0 member: Group :: Z funcÌ16Í()Ö0 function: func() geany-2.0/tests/ctags/ruby-sf-bug-364.rb0000644000175000017500000000023214514252267014650 00000000000000class D def self.x? end def self.y! end def self.z=(a) end def self._a? end def self._b! end def self._c=(a) end end D._c=1 D.z=1 geany-2.0/tests/ctags/interface_properties.cs0000644000175000017500000000227014514252267016416 00000000000000// cs_interface_properties.cs // Interface Properties using System; interface IEmployee { string Name { get; set; } int Counter { get; } } public class Employee: IEmployee { public static int numberOfEmployees; private int counter; private string name; // Read-write instance property: public string Name { get { return name; } set { name = value; } } // Read-only instance property: public int Counter { get { return counter; } } // Constructor: public Employee() { counter = ++counter + numberOfEmployees; } } public class MainClass { public static void Main() { Console.Write("Enter number of employees: "); string s = Console.ReadLine(); Employee.numberOfEmployees = int.Parse(s); Employee e1 = new Employee(); Console.Write("Enter the name of the new employee: "); e1.Name = Console.ReadLine(); Console.WriteLine("The employee information:"); Console.WriteLine("Employee number: {0}", e1.Counter); Console.WriteLine("Employee name: {0}", e1.Name); } } geany-2.0/tests/ctags/simple.diff0000644000175000017500000000733214514252267014002 00000000000000diff --git a/main/parsers.h b/main/parsers.h index 8000fa0..5332052 100644 --- a/main/parsers.h +++ b/main/parsers.h @@ -28,6 +28,7 @@ CsharpParser, \ CobolParser, \ DParser, \ + DiffParser, \ DosBatchParser, \ EiffelParser, \ ErlangParser, \ diff --git a/parsers/diff.c b/parsers/diff.c new file mode 100644 index 0000000..a1bf5f3 --- /dev/null +++ b/parsers/diff.c @@ -0,0 +1,134 @@ +/* +* +* Copyright (c) 2000-2001, Darren Hiebert +* +* This source code is released for free distribution under the terms of the +* GNU General Public License. +* +* This module contains functions for generating tags for diff files (based on Sh parser). +*/ + +/* +* INCLUDE FILES +*/ +#include "general.h" /* must always come first */ + +#include +#include + +#include "parse.h" +#include "read.h" +#include "vstring.h" + +/* +* DATA DEFINITIONS +*/ +typedef enum { + K_FUNCTION +} diffKind; + +static kindOption DiffKinds [] = { + { TRUE, 'f', "compared file", "compared files"} +}; + +enum { + DIFF_DELIM_MINUS = 0, + DIFF_DELIM_PLUS +}; + +static const char *DiffDelims[2] = { + "--- ", + "+++ " +}; + +/* +* FUNCTION DEFINITIONS +*/ + +static const unsigned char *stripAbsolute (const unsigned char *filename) +{ + const unsigned char *tmp; + + /* strip any absolute path */ + if (*filename == '/' || *filename == '\\') + { + boolean skipSlash = TRUE; + + tmp = (const unsigned char*) strrchr ((const char*) filename, '/'); + if (tmp == NULL) + { /* if no / is contained try \ in case of a Windows filename */ + tmp = (const unsigned char*) strrchr ((const char*) filename, '\\'); + if (tmp == NULL) + { /* last fallback, probably the filename doesn't contain a path, so take it */ + tmp = filename; + skipSlash = FALSE; + } + } + + /* skip the leading slash or backslash */ + if (skipSlash) + tmp++; + } + else + tmp = filename; + + return tmp; +} + +static void findDiffTags (void) +{ + vString *filename = vStringNew (); + const unsigned char *line, *tmp; + int delim = DIFF_DELIM_MINUS; + + while ((line = fileReadLine ()) != NULL) + { + const unsigned char* cp = line; + + if (strncmp ((const char*) cp, DiffDelims[delim], 4u) == 0) + { + cp += 4; + if (isspace ((int) *cp)) continue; + /* when original filename is /dev/null use the new one instead */ + if (delim == DIFF_DELIM_MINUS && + strncmp ((const char*) cp, "/dev/null", 9u) == 0 && + (cp[9] == 0 || isspace (cp[9]))) + { + delim = DIFF_DELIM_PLUS; + continue; + } + + tmp = stripAbsolute (cp); + + if (tmp != NULL) + { + while (! isspace(*tmp) && *tmp != '\0') + { + vStringPut(filename, *tmp); + tmp++; + } + + vStringTerminate(filename); + makeSimpleTag (filename, DiffKinds, K_FUNCTION); + vStringClear (filename); + } + + /* restore default delim */ + delim = DIFF_DELIM_MINUS; + } + } + vStringDelete (filename); +} + +extern parserDefinition* DiffParser (void) +{ + static const char *const extensions [] = { "diff", "patch", NULL }; + parserDefinition* const def = parserNew ("Diff"); + def->kinds = DiffKinds; + def->kindCount = KIND_COUNT (DiffKinds); + def->extensions = extensions; + def->parser = findDiffTags; + return def; +} + +/* vi:set tabstop=8 shiftwidth=4: */ diff --git a/source.mak b/source.mak index 2550028..eaa9154 100644 --- a/source.mak +++ b/source.mak @@ -44,6 +44,7 @@ PARSER_SOURCES = \ $(PARSER_DIR)/clojure.c \ $(PARSER_DIR)/css.c \ $(PARSER_DIR)/cobol.c \ + $(PARSER_DIR)/diff.c \ $(PARSER_DIR)/dosbatch.c \ $(PARSER_DIR)/eiffel.c \ $(PARSER_DIR)/erlang.c \ --- a/Units/review-needed.r/simple.ksh.t/expected.tags +++ /dev/null @@ -1,2 +0,0 @@ -f1 input.ksh /^f1() {$/;" f -f2 input.ksh /^function f2 {$/;" f geany-2.0/tests/ctags/bug1764148.py.tags0000644000175000017500000000005214514252267014512 00000000000000PyFuncÌ16Í(msg)Ö0 function: PyFunc(msg) geany-2.0/tests/ctags/enum.c.tags0000644000175000017500000000037314514252267013722 00000000000000ENUM_1Ì4Îtest_enumerationÖ0 enumerator: test_enumeration :: ENUM_1 ENUM_2Ì4Îtest_enumerationÖ0 enumerator: test_enumeration :: ENUM_2 ENUM_3Ì4Îtest_enumerationÖ0 enumerator: test_enumeration :: ENUM_3 test_enumerationÌ2Ö0 enum: test_enumeration geany-2.0/tests/ctags/simple.json.tags0000644000175000017500000000155114514252267014775 000000000000000Ì64ÎphoneNumbersÖ0 member: phoneNumbers :: 0 1Ì64ÎphoneNumbersÖ0 member: phoneNumbers :: 1 addressÌ64Ö0 member: address ageÌ64Ö0 member: age childrenÌ64Ö0 member: children cityÌ64ÎaddressÖ0 member: address :: city firstNameÌ64Ö0 member: firstName height_cmÌ64Ö0 member: height_cm isAliveÌ64Ö0 member: isAlive lastNameÌ64Ö0 member: lastName numberÌ64ÎphoneNumbers.0Ö0 member: phoneNumbers.0 :: number numberÌ64ÎphoneNumbers.1Ö0 member: phoneNumbers.1 :: number phoneNumbersÌ64Ö0 member: phoneNumbers postalCodeÌ64ÎaddressÖ0 member: address :: postalCode spouseÌ64Ö0 member: spouse stateÌ64ÎaddressÖ0 member: address :: state streetAddressÌ64ÎaddressÖ0 member: address :: streetAddress typeÌ64ÎphoneNumbers.0Ö0 member: phoneNumbers.0 :: type typeÌ64ÎphoneNumbers.1Ö0 member: phoneNumbers.1 :: type geany-2.0/tests/ctags/strings.rb0000644000175000017500000000144314514252267013672 00000000000000 class A def a dummy = "\n while true do \n" end def b dummy = %Q{\n while true do \n} end def c dummy = %{\n while true do \n} end def d dummy = %/\n while true do \n/ end # raw strings def e dummy = ' while true do ' end def f dummy = %q{ while true do } end # sentinel for last test def sentinel end end v = " def not_me1 print \"i'm not a function\" end " print v, "\n" v = %Q{ def not_me2 print "i'm not a function" end } print v, "\n" v = %{{ def not_me3 print "i'm not a function" end } print v, "\n" v = %/ def not_me4 print "i'm not a function" end \/ / print v, "\n" # raw strings v = ' def not_me5 print "i\'m not a function" end ' print v, "\n" v = %q{ def not_me5 print "i'm not a function" end \} } print v, "\n" geany-2.0/tests/ctags/bug1585745.cpp.tags0000644000175000017500000000046114514252267014654 00000000000000Class5Ì1Ö0 class: Class5 ~Class1Ì16Í()ÎClass1Ö0 function: Class1 :: ~Class1() ~Class2Ì16Í()ÎClass2Ö0 function: Class2 :: ~Class2() ~Class3Ì16Í()ÎClass3Ö0 function: Class3 :: ~Class3() ~Class4Ì16Í()ÎClass4Ö0 function: Class4 :: ~Class4() ~Class5Ì16Í()ÎClass5Ö0 function: Class5 :: ~Class5() geany-2.0/tests/ctags/bug872494.cpp0000644000175000017500000000243614514252267013642 00000000000000/* Bugs item #872494, was opened at 2004-01-07 16:33 Message generated for change (Tracker Item Submitted) made by Item Submitter You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=106556&aid=872494&group_id=6556 Category: None Group: None Status: Open Resolution: None Priority: 5 Submitted By: Igor Proskuriakov (proskig) Assigned to: Nobody/Anonymous (nobody) Summary: C++ class template specialization Initial Comment: Hi, some time ago I posted a bug related to C++ member template, which was fixed using patch bug849591.diff. Many thanks - it really fixed the problem ! Now about a different one. When parsing C++ file ctags seems to ignore template specialization, but I think that it maybe useful to add it as a configurable feature. Another problem is that template specialization seems to confuse patched version of ctags (patch bug849591.diff). When running a patched version against the following file */ template class TemplClass { double i;}; template<> class TemplClass< char* > { int i;}; class FooClass2{}; /* it does not generate tag for FooClass2 while ctags 5.5.2 does generate tag for FooClass2. Neither of them generate tag for specialization TemplClass. thanks in advance and let me know should you need more info! Igor */ geany-2.0/tests/ctags/intro_orig.tex.tags0000644000175000017500000000307214514252267015506 00000000000000Common Greek lettersÌ65536ÎSpecial SymbolsÖ0 macro: Special Symbols :: Common Greek letters EquationsÌ64Ö0 member: Equations FiguresÌ64Ö0 member: Figures IntroductionÌ64Ö0 member: Introduction ListsÌ64Ö0 member: Lists Literal textÌ64Ö0 member: Literal text Special SymbolsÌ64Ö0 member: Special Symbols Special symbolsÌ65536ÎSpecial SymbolsÖ0 macro: Special Symbols :: Special symbols TablesÌ64Ö0 member: Tables \EndÌ16Ö0 function: \End \color{red}Use of ColorÌ64Ö0 member: \color{red}Use of Color \label{morefig}SubfiguresÌ64Ö0 member: \label{morefig}Subfigures \lbÌ16Ö0 function: \lb \rbÌ16Ö0 function: \rb \rvÌ16Ö0 function: \rv alignÌ1Ö0 class: align boxedÌ1Ö0 class: boxed casesÌ1Ö0 class: cases centerÌ1Ö0 class: center commentÌ1Ö0 class: comment documentÌ1Ö0 class: document enumerateÌ1Ö0 class: enumerate eq:fineÌ2048Ö0 struct: eq:fine eq:isingÌ2048Ö0 struct: eq:ising eq:mdivÌ2048Ö0 struct: eq:mdiv equationÌ1Ö0 class: equation fig:ljÌ2048Ö0 struct: fig:lj fig:qm/complexfunctionsÌ2048Ö0 struct: fig:qm/complexfunctions fig:typicalÌ2048Ö0 struct: fig:typical figureÌ1Ö0 class: figure itemizeÌ1Ö0 class: itemize latexÌ8Ö0 field: latex pmatrixÌ1Ö0 class: pmatrix subequationsÌ1Ö0 class: subequations tab:5/tcÌ2048Ö0 struct: tab:5/tc tableÌ1Ö0 class: table tabularÌ1Ö0 class: tabular thebibliographyÌ1Ö0 class: thebibliography theorem1Ì1Ö0 class: theorem1 verbatimÌ1Ö0 class: verbatim websiteÌ8Ö0 field: website geany-2.0/tests/ctags/hex2dec.sql.tags0000644000175000017500000000010214514252267014643 00000000000000hex2decÌ16Ö0 function: hex2dec num2hexÌ16Ö0 function: num2hex geany-2.0/tests/ctags/css-at-rules.css0000644000175000017500000000062314514252267014707 00000000000000 @import "foo.css"; @namespace url(http://www.w3.org/1999/xhtml); @namespace svg url(http://www.w3.org/2000/svg); @media screen { body { font-size: 10pt; } } @media print { body { font-size: 12px; } } @media screen, print { body { line-height: 1.2 } } @page :first { margin: 2in; } @font-face { font-family: Sample; src: local("Sample"), url(Sample.ttf); } html { color: blue; } geany-2.0/tests/ctags/bug1799343-1.cpp.tags0000644000175000017500000000030614514252267015011 00000000000000CÌ2048Ö0 struct: C DÌ16Í()ÎDÖ0 function: D :: D() DÌ2048Ö0 struct: D mainÌ16Í(void)Ö0Ïint function: int main(void) xÌ64ÎCÖ0Ïint member: int C :: x ~DÌ16Í()ÎDÖ0 function: D :: ~D() geany-2.0/tests/ctags/keyword_public.cs.tags0000644000175000017500000000036414514252267016163 00000000000000MainÌ128Í()ÎMyClass2Ö0Ïpublic void method: public void MyClass2 :: Main() MyClass1Ì1Ö0 class: MyClass1 MyClass2Ì1Ö0 class: MyClass2 xÌ8ÎMyClass1Ö0Ïint field: int MyClass1 :: x yÌ8ÎMyClass1Ö0Ïint field: int MyClass1 :: y geany-2.0/tests/ctags/c-trigraphs.c.tags0000644000175000017500000000110614514252267015174 00000000000000AÌ65536Ö0 macro: A BÌ65536Ö0 macro: B DÌ65536Ö0 macro: D EÌ65536Ö0 macro: E FÌ65536Ö0 macro: F M3_INITÌ131072Í(a,b,c)Ö0 macro_arg: M3_INIT(a,b,c) STRINGIFYÌ131072Í(x)Ö0 macro_arg: STRINGIFY(x) STRINGIFY_INTERNÌ131072Í(x)Ö0 macro_arg: STRINGIFY_INTERN(x) bufÌ64ÎstrÖ0Ïchar * member: char * str :: buf lenÌ64ÎstrÖ0Ïunsigned int member: unsigned int str :: len mainÌ16Í(void)Ö0Ïint function: int main(void) matrix3Ì4096Ö0Ïint[3] typedef: int[3] matrix3 sizeÌ64ÎstrÖ0Ïunsigned int member: unsigned int str :: size strÌ2048Ö0 struct: str geany-2.0/tests/ctags/js-signature.js.tags0000644000175000017500000000064314514252267015563 00000000000000ClsÌ1Í(name)Ö0 class: Cls(name) f1Ì16Í()Ö0 function: f1() f2Ì16Í(arg1, arg2)Ö0 function: f2(arg1, arg2) f3Ì16Í( arg1, arg2, arg3 )Ö0 function: f3( arg1, arg2, arg3 ) f4Ì16Í(a, b, c)Ö0 function: f4(a, b, c) get_nameÌ128Í()ÎClsÖ0 method: Cls :: get_name() helloÌ128Í(tpl)ÎClsÖ0 method: Cls :: hello(tpl) mainÌ16Í()Ö0 function: main() set_nameÌ128Í(name)ÎClsÖ0 method: Cls :: set_name(name) geany-2.0/tests/ctags/simple.json0000644000175000017500000000065514514252267014044 00000000000000{ "firstName": "John", "lastName": "Smith", "isAlive": true, "age": 25, "height_cm": 167.6, "address": { "streetAddress": "21 2nd Street", "city": "New York", "state": "NY", "postalCode": "10021-3100" }, "phoneNumbers": [ { "type": "home", "number": "212 555-1234" }, { "type": "office", "number": "646 555-4567" } ], "children": [], "spouse": null } geany-2.0/tests/ctags/procpoint.f900000644000175000017500000000117514514252267014213 00000000000000module Test implicit none procedure(ProcOne), pointer :: MyProc => null(), & MyOtherProc => ProcTwo real, parameter :: myparameter contains function ProcOne(arg1, optformat) ! not relevant end function ProcOne function ProcTwo(arg1, optformat) ! not relevant end function ProcTwo end module Test program Main implicit none ! deliberately break up the line to make sure the tagparser doesn't choke on awkward cases procedure(:), pointer :: ProcPointOne & => null(), ProcPointTwo => & null() real :: variable, variable_two integer :: variable_three ProcPointOne => ProcTwo end program Main geany-2.0/tests/ctags/implied_program.f0000644000175000017500000000017714514252267015200 00000000000000C Bug reported by Brian Helinski on 28 Feb 2003 ! implicit program main integer i i = 5 write(*,*) i end geany-2.0/tests/ctags/bit_field.c0000644000175000017500000000117614514252267013744 00000000000000struct bit_fields { unsigned int a: 1; unsigned int b: 1; unsigned int c: 2; }; struct { unsigned sign : 1; unsigned exp : _FP_EXPBITS_D; unsigned frac1 : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0) - _FP_W_TYPE_SIZE; unsigned frac0 : _FP_W_TYPE_SIZE; }; struct shortname_info { unsigned char lower:1, upper:1, valid:1; }; // Problem reported by Michael Brown on 23 October 2001. typedef struct { BYTE public: 1; BYTE bad2: 1; BYTE group: 1; BYTE personal: 1; } bitfield_flags; typedef struct { BYTE this; BYTE public; BYTE private; BYTE that; } mystruct; geany-2.0/tests/ctags/state_machine.v.tags0000644000175000017500000000026214514252267015602 00000000000000S0Ì16384Ö0 variable: S0 S1Ì16384Ö0 variable: S1 S2Ì16384Ö0 variable: S2 S3Ì16384Ö0 variable: S3 next_stateÌ16384Ö0 variable: next_state stateÌ16384Ö0 variable: state geany-2.0/tests/ctags/js-string-continuation.js0000644000175000017500000000026114514252267016637 00000000000000 var o = { "first": function(){}, "sec\ ond": function(){}, "\ t\ h\ i\ r\ d\ ": function(){}, "fourth": function(){}, }; o.first(); o.second(); o.third(); o.fourth(); geany-2.0/tests/ctags/julia-corner_cases.jl.tags0000644000175000017500000000700214514252267016705 00000000000000BaseÌ256Ö0 namespace: Base FooÌ2048Ö0 struct: Foo FooÌ4096Ö0 typedef: Foo Mod1Ì256Ö0 namespace: Mod1 Mod2Ì256Ö0 namespace: Mod2 Module1Ì256Ö0 namespace: Module1 Module10Ì256ÎMyModuleÖ0 namespace: MyModule :: Module10 Module11Ì256ÎMyModuleÖ0 namespace: MyModule :: Module11 Module13Ì256Ö0 namespace: Module13 Module2Ì256Ö0 namespace: Module2 Module3Ì256Ö0 namespace: Module3 Module4Ì256Ö0 namespace: Module4 Module5Ì256Ö0 namespace: Module5 Module6Ì256Ö0 namespace: Module6 Module7Ì256Ö0 namespace: Module7 Module8Ì256ÎMyModuleÖ0 namespace: MyModule :: Module8 Module9Ì256ÎMyModuleÖ0 namespace: MyModule :: Module9 MyModuleÌ256Ö0 namespace: MyModule OurRationalÌ2048Í{T<:Integer}Ö0 struct: OurRational{T<:Integer} OurRational{Int16}Ì16Í(num::T, den::T) where T<:Integer Ö0 function: OurRational{Int16}(num::T, den::T) where T<:Integer OurRational{Int64}Ì16Í(num::T, den::T, test::T) where T<:Integer ÎOurRationalÖ0 function: OurRational :: OurRational{Int64}(num::T, den::T, test::T) where T<:Integer OurRational{Int8}Ì16Í(num::T, den::T) where T<:Integer ÎOurRationalÖ0 function: OurRational :: OurRational{Int8}(num::T, den::T) where T<:Integer OurRational{T}Ì16Í(num::T, den::T) where T<:IntegerÎOurRationalÖ0 function: OurRational :: OurRational{T}(num::T, den::T) where T<:Integer PointÌ2048Í{T}Ö0 struct: Point{T} PointyÌ4096Ö0 typedef: Pointy TestÌ2048Ö0 struct: Test aÌ64Í::Float64ÎTestÖ0 member: Test :: a::Float64 bÌ64Í::Float64ÎTestÖ0 member: Test :: b::Float64 barÌ16Í(x, y)ÎFooÖ0 function: Foo :: bar(x, y) cellÌ16Í(dims::(Integer...))Ö0 function: cell(dims::(Integer...)) denÌ64Í::TÎOurRationalÖ0 member: OurRational :: den::T elsizeÌ16Í(::AbstractArray{T}) where {T} Ö0 function: elsize(::AbstractArray{T}) where {T} elsizeÌ16Í(::AbstractArray{T}) where TÖ0 function: elsize(::AbstractArray{T}) where T fÌ16Í(x::FooBar)Ö0 function: f(x::FooBar) fooÌ16Í(x::(Int,))Ö0 function: foo(x::(Int,)) fooÌ16Í()Ö0 function: foo() fooÌ16Í(x)ÎBazÖ0 function: Baz :: foo(x) foo_bar!Ì16Í(x,y)Ö0 function: foo_bar!(x,y) func1Ì32768ÎModule11Ö0 externvar: Module11 :: func1 func1Ì32768ÎModule13Ö0 externvar: Module13 :: func1 func1Ì32768ÎModule2Ö0 externvar: Module2 :: func1 func1Ì32768ÎModule4Ö0 externvar: Module4 :: func1 func1Ì32768ÎModule7Ö0 externvar: Module7 :: func1 func2Ì32768ÎModule11Ö0 externvar: Module11 :: func2 func2Ì32768ÎModule2Ö0 externvar: Module2 :: func2 func2Ì32768ÎModule6Ö0 externvar: Module6 :: func2 func2Ì32768ÎModule7Ö0 externvar: Module7 :: func2 func3Ì16Í(a::Int)ÎMyModuleÖ0 function: MyModule :: func3(a::Int) func3Ì32768ÎModule11Ö0 externvar: Module11 :: func3 func4Ì16Í(a::Int)ÎMyModuleÖ0 function: MyModule :: func4(a::Int) func5Ì16Í(b::Int)ÎMyModule.func4Ö0 function: MyModule.func4 :: func5(b::Int) gÌ16Í(x, y)::Int8Ö0 function: g(x, y)::Int8 myfunÌ16Í()Ö0 function: myfun() normÌ16Í(p::Point{<:Real})Ö0 function: norm(p::Point{<:Real}) numÌ64Í::TÎOurRationalÖ0 member: OurRational :: num::T same_type_numericÌ16Í(x::T, y::T) where {T <: Number} Ö0 function: same_type_numeric(x::T, y::T) where {T <: Number} same_type_numericÌ16Í(x::T, y::T) where T Ö0 function: same_type_numeric(x::T, y::T) where T showÌ32768ÎBaseÖ0 externvar: Base :: show testÌ16Í(x)Ö0 function: test(x) testÌ64Í::TÎOurRationalÖ0 member: OurRational :: test::T test_docstringÌ16Ö0 function: test_docstring xÌ64Í::BarÎFooÖ0 member: Foo :: x::Bar xÌ64Í::TÎPointÖ0 member: Point :: x::T yÌ64Í::TÎPointÖ0 member: Point :: y::T yÌ16384Ö0 variable: y geany-2.0/tests/ctags/strings.php0000644000175000017500000000037114514252267014055 00000000000000(_: &'lifetime isize) { let s = '"'; let s = '}'; let s = '\''; fn not_hidden_by_char() {} } fn preserve_string_delims(_bar: extern r#"C"# fn()) {} pub struct A { foo: fn() -> isize, bar: isize } pub struct B { #[cfg(test)] foo: isize, bar: isize } pub struct C where T: Send { a: T } pub trait D where T: Send { } impl D for C where T: Send { } pub fn where_foo(a: T) where T: Send { } /* * fn ignored_in_comment() {} */ // fn ignored_in_comment() {} /* /* * */ fn ignored_in_nested_comment() {} */ static size: usize = 1; #[cfg(test)] struct S1 { only_field: [isize; size] } macro_rules! test_macro { () => {1} } macro_rules! ignore {($($x:tt)*) => (())} fn yada(a:isize, c:Foo, b:test_input2::SomeStruct) -> String { a.to_string() } fn main() { use test_input2::*; let a=Foo{foo_field_1:2}; a.my_method(1); let c=Animal::a_cat(3); let d=Foo{foo_field_1:a.foo_field_1+2}; a.test(); println!("{}", a.foo_field_1.to_string()); ignore! ( fn ignored_inside_macro() {} ); ignore! [ fn ignored_inside_macro() {} ]; ignore! { fn ignored_inside_macro() {} } let _ = "fn ignored_in_string() {} "; let _ = r##"fn ignored_in_raw_string() {}""##; fn nested() {} } struct Bar(isize); struct Baz(isize); struct Foo{foo_field_1:isize} struct Foo2 { x:isize, y:isize } impl Foo { fn my_method(&self,_:isize){ println!("{}", "my_method of foo");} } enum Animal { a_anteater(isize), a_bear(isize), a_cat(isize), a_dog(isize), } trait Testable { fn test(&self); fn test1(&self); fn test2(&self); } trait DoZ { fn do_z(&self); } impl Testable for Foo { fn test(&self) { println!("{}", self.foo_field_1.to_string()); } fn test1(&self) { println!("{}", self.foo_field_1.to_string()); } fn test2(&self) { println!("{}", self.foo_field_1.to_string()); } } impl DoZ for Foo { fn do_z(&self) { println!("{}", self.foo_field_1.to_string()); } } trait SuperTraitTest:Testable+DoZ { } fn gfunc(x:&X) { let a1=Animal::a_anteater(1); let a2=Animal::a_bear(1); let a3=Animal::a_cat(1); let a4=Animal::a_dog(1); x.test(); x.do_z(); } struct TraitedStructTest { x:X } trait ParametrizedTrait { fn test(&self); } impl ParametrizedTrait for TraitedStructTest { fn test(&self) { } } fn some2(a:Animal) { match a { Animal::a_cat(x)=> println!("{}", "cat"), _ => println!("{}", "not a cat") } } geany-2.0/tests/ctags/bug1907083.cpp0000644000175000017500000000026314514252267013710 00000000000000// All of these should have "class:C", but m2-m4 have "class C::C" with ctags 5.7. C::T * C::m1() {} C::T * const C::m2() {} C::T const * C::m3() {} C::T const * const C::m4() {} geany-2.0/tests/ctags/refcurs.sql0000644000175000017500000000375114514252267014052 00000000000000rem ----------------------------------------------------------------------- rem URL: http://www.orafaq.com/scripts/plsql/refcurs.txt rem Filename: refcurs.sql rem Purpose: Pass result sets (REF CURSOR) between procedures and rem functions rem Date: 15-Jun-2001 rem Author: Frank Naude (frank@ibi.co.za) rem ----------------------------------------------------------------------- set serveroutput on -- Define TYPES package separately to be available to all programming -- environments... CREATE OR REPLACE PACKAGE types AS TYPE cursortyp is REF CURSOR; -- use weak form END; / -- Create test package to demonstrate passing result sets... CREATE OR REPLACE PACKAGE test_ref_cursor AS PROCEDURE main; FUNCTION get_cursor_ref(typ NUMBER) RETURN types.cursortyp; PROCEDURE process_cursor(cur types.cursortyp); END; / show errors CREATE OR REPLACE PACKAGE BODY test_ref_cursor AS -- Main program entry point PROCEDURE main IS BEGIN process_cursor( get_cursor_ref(1) ); process_cursor( get_cursor_ref(2) ); END; -- Get and return a CURSOR REF/ Result Set FUNCTION get_cursor_ref(typ NUMBER) RETURN types.cursortyp IS cur types.cursortyp; BEGIN if typ = 1 THEN OPEN cur FOR SELECT * FROM emp WHERE ROWNUM < 5; ELSE OPEN cur FOR SELECT * FROM dept WHERE ROWNUM < 5; END IF; RETURN cur; END; -- Process rows for an EMP or DEPT cursor PROCEDURE process_cursor(cur types.cursortyp) IS empRec emp%ROWTYPE; deptRec dept%ROWTYPE; BEGIN LOOP FETCH cur INTO empRec; -- Maybe it was an EMP cursor, try to fetch... EXIT WHEN cur%NOTFOUND; dbms_output.put_line('EMP ROW: '||empRec.ename); END LOOP; EXCEPTION WHEN ROWTYPE_MISMATCH THEN -- OK, so it was't EMP, let's try DEPT. LOOP FETCH cur INTO deptRec; EXIT WHEN cur%NOTFOUND; dbms_output.put_line('DEPT ROW: '||deptRec.dname); END LOOP; END; END; / show errors EXEC test_ref_cursor.main; geany-2.0/tests/ctags/enumerators.f900000644000175000017500000000174214514252267014542 00000000000000module Enums real :: somevar ! we now have enumerators in F2003/8, for the sake of interop with C enum, bind(c) ! unnamed 1 enumerator :: red =1, blue enumerator gold, silver, bronze enumerator :: purple end enum ! here follow nonstandard enum declarations, which may become valid in a later standard ! no real harm implementing these as long as valid stuff isn't broken enum enumerator :: no_c_binding end enum enum :: Colons enumerator :: r end enum enum BodyPart enumerator :: arm, leg end enum enum(8) Paren_kind enumerator :: b end enum enum*8 Aster_kind enumerator :: c end enum enum(8) :: Paren_colon enumerator :: d end enum enum*8 :: Aster_colon enumerator :: e end enum enum, bind(c) :: Name_colon enumerator :: d end enum ! another entry to verify the parsing hasn't broken real, parameter :: othervar contains function Func(arg) ! ... end function Func end module Enums geany-2.0/tests/ctags/make-parentheses.mak.tags0000644000175000017500000000022214514252267016531 00000000000000$(A)-$(A:.c=.o)Ì16Ö0 function: $(A)-$(A:.c=.o) ${B}-${B:.c=.o}Ì16Ö0 function: ${B}-${B:.c=.o} AÌ65536Ö0 macro: A BÌ65536Ö0 macro: B geany-2.0/tests/ctags/continuation.mak0000644000175000017500000000006214514252267015054 00000000000000 A = \ a=b \ \ b=c \ \ c=d \ \ d=e \ B = dummy geany-2.0/tests/ctags/keyword_names.f900000644000175000017500000000062314514252267015042 00000000000000! For some reason, the Fortran standard does not prohibit this... module Program type Data integer :: contents end type Data integer :: i interface Program function myFunc(arg) !... end function myFunc end interface Program contains function MyFunc(arg) ! ... end function MyFunc end module Program program Interface use Program ! ... end program Interface geany-2.0/tests/ctags/misc_types.f.tags0000644000175000017500000000017314514252267015136 00000000000000INFOOBARÌ16384ÎspecsÖ0 variable: specs :: INFOOBAR MÌ16384ÎspecsÖ0 variable: specs :: M specsÌ2048Ö0 struct: specs geany-2.0/tests/ctags/matlab_backtracking.m.tags0000644000175000017500000000004514514252267016727 00000000000000backtrackÌ16Ö0 function: backtrack geany-2.0/tests/ctags/bug722501.sql0000644000175000017500000000113714514252267013633 00000000000000/* The PL/SQL parser (v1.6) does not parse a standalone procedure or function (i.e., not part of a package) when the SQL is in the form */ CREATE OR REPLACE PROCEDURE foo AS /* or IS*/ BEGIN DECLARE l_foo NUMBER; BEGIN l_foo := 1; END; END; /* When this is processed the only tag reported is Procedure foo. If you remove the line with AS, the variable l_foo is seen, but then the procedure will not compile in Oracle. Functions seem to have similar problems in that the parser will not see inside the function, but removing the IS or AS does not remedy the problem for a function. */ geany-2.0/tests/ctags/keyword_extern.cs.tags0000644000175000017500000000041214514252267016204 00000000000000MainÌ128Í()ÎMyClassÖ0Ïpublic int method: public int MyClass :: Main() MessageBoxÌ128Í(int h, string m, string c, int type)ÎMyClassÖ0Ï[]public int method: []public int MyClass :: MessageBox(int h, string m, string c, int type) MyClassÌ1Ö0 class: MyClass geany-2.0/tests/ctags/vhdl-local.vhd0000644000175000017500000001376514514252267014416 00000000000000-- -- Taken from rtl/commonlib/types_util.vhd of https://github.com/sergeykhbr/riscv_vhdl -- ----------------------------------------------------------------------------- --! @file --! @copyright Copyright 2015 GNSS Sensor Ltd. All right reserved. --! @author Sergey Khabarov - sergeykhbr@gmail.com --! @brief Package for common testbenches implementation. ------------------------------------------------------------------------------ library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; library std; use std.textio.all; package types_util is function strlen(s: in string) return integer; function StringToUVector(inStr: string) return std_ulogic_vector; function StringToSVector(inStr: string) return std_logic_vector; function UnsignedToSigned(inUnsigned: std_ulogic_vector) return std_logic_vector; function SignalFromString(inStr: string; ind : integer ) return std_logic; function SymbolToSVector(inStr: string; idx: integer) return std_logic_vector; function tost(v:std_logic_vector) return string; function tost(v:std_logic) return string; function tost(i : integer) return string; procedure print(s : string); end; package body types_util is function strlen(s: in string) return integer is variable n: integer:=0; variable sj: integer:=s'left; begin loop if sj>s'right then exit; elsif s(sj)=NUL then exit; --sequential if protects sj > length else sj:=sj+1; n:=n+1; end if; end loop; return n; end strlen; function SignalFromString(inStr: string; ind : integer ) return std_logic is variable temp: std_logic := 'X'; begin if(inStr(inStr'high-ind)='1') then temp := '1'; elsif(inStr(inStr'high-ind)='0') then temp := '0'; end if; return temp; end function SignalFromString; function StringToUVector(inStr: string) return std_ulogic_vector is variable temp: std_ulogic_vector(inStr'range) := (others => 'X'); begin for i in inStr'range loop -- if(inStr(inStr'high-i+1)='1') then temp(i) := '1'; elsif(inStr(inStr'high-i+1)='0') then temp(i) := '0'; end if; end loop; return temp(inStr'high downto 1); end function StringToUVector; -- conversion function function StringToSVector(inStr: string) return std_logic_vector is variable temp: std_logic_vector(inStr'range) := (others => 'X'); begin for i in inStr'range loop -- if(inStr(inStr'high-i+1)='1') then temp(i) := '1'; elsif(inStr(inStr'high-i+1)='0') then temp(i) := '0'; end if; end loop; return temp(inStr'high downto 1); end function StringToSVector; function SymbolToSVector(inStr: string; idx: integer) return std_logic_vector is constant ss: string(1 to inStr'length) := inStr; variable c : integer; variable temp: std_logic_vector(7 downto 0) := (others => 'X'); begin c := character'pos(ss(idx+1)); for i in 0 to 7 loop -- temp(i) := to_unsigned(c,8)(i); end loop; return temp; end function SymbolToSVector; function UnsignedToSigned(inUnsigned: std_ulogic_vector) return std_logic_vector is variable temp: std_logic_vector(inUnsigned'length-1 downto 0) := (others => 'X'); variable i: integer:=0; begin while i < inUnsigned'length loop if(inUnsigned(i)='1') then temp(i) := '1'; elsif(inUnsigned(i)='0') then temp(i) := '0'; end if; i := i+1; end loop; return temp; end function UnsignedToSigned; subtype nibble is std_logic_vector(3 downto 0); function todec(i:integer) return character is begin case i is when 0 => return('0'); when 1 => return('1'); when 2 => return('2'); when 3 => return('3'); when 4 => return('4'); when 5 => return('5'); when 6 => return('6'); when 7 => return('7'); when 8 => return('8'); when 9 => return('9'); when others => return('0'); end case; end; function tohex(n:nibble) return character is begin case n is when "0000" => return('0'); when "0001" => return('1'); when "0010" => return('2'); when "0011" => return('3'); when "0100" => return('4'); when "0101" => return('5'); when "0110" => return('6'); when "0111" => return('7'); when "1000" => return('8'); when "1001" => return('9'); when "1010" => return('a'); when "1011" => return('b'); when "1100" => return('c'); when "1101" => return('d'); when "1110" => return('e'); when "1111" => return('f'); when others => return('X'); end case; end; function tost(v:std_logic_vector) return string is constant vlen : natural := v'length; --' constant slen : natural := (vlen+3)/4; variable vv : std_logic_vector(0 to slen*4-1) := (others => '0'); variable s : string(1 to slen); variable nz : boolean := false; variable index : integer := -1; variable vector : bit_vector(0 TO 7); alias reverse_vector : bit_vector ( vector'length DOWNTO 1 ) IS vector ; begin vv(slen*4-vlen to slen*4-1) := v; for i in 0 to slen-1 loop if (vv(i*4 to i*4+3) = "0000") and nz and (i /= (slen-1)) then index := i; else nz := false; s(i+1) := tohex(vv(i*4 to i*4+3)); end if; end loop; if ((index +2) = slen) then return(s(slen to slen)); else return(string'("0x") & s(index+2 to slen)); end if; --' end; function tost(v:std_logic) return string is begin if to_x01(v) = '1' then return("1"); else return("0"); end if; end; function tost(i : integer) return string is variable L : line; variable s, x : string(1 to 128); variable n, tmp : integer := 0; begin tmp := i; if i < 0 then tmp := -i; end if; loop s(128-n) := todec(tmp mod 10); tmp := tmp / 10; n := n+1; if tmp = 0 then exit; end if; end loop; x(1 to n) := s(129-n to 128); if i < 0 then return "-" & x(1 to n); end if; return(x(1 to n)); end; procedure print(s : string) is variable L : line; begin L := new string'(s); writeline(output, L); end; end; geany-2.0/tests/ctags/bug2411878.cs.tags0000644000175000017500000000010714514252267014470 00000000000000CÌ1Ö0 class: C m_nameÌ8ÎCÖ0ÏSystem field: System C :: m_name geany-2.0/tests/ctags/keyword_virtual.cs.tags0000644000175000017500000000305314514252267016371 00000000000000AreaÌ128Í()ÎTestClass.CircleÖ0Ïpublic override double method: public override double TestClass.Circle :: Area() AreaÌ128Í()ÎTestClass.CylinderÖ0Ïpublic override double method: public override double TestClass.Cylinder :: Area() AreaÌ128Í()ÎTestClass.DimensionsÖ0Ïpublic virtual double method: public virtual double TestClass.Dimensions :: Area() AreaÌ128Í()ÎTestClass.SphereÖ0Ïpublic override double method: public override double TestClass.Sphere :: Area() CircleÌ1ÎTestClassÖ0 class: TestClass :: Circle CircleÌ128Í(double r)ÎTestClass.CircleÖ0 method: TestClass.Circle :: Circle(double r) CylinderÌ1ÎTestClassÖ0 class: TestClass :: Cylinder CylinderÌ128Í(double r, double h)ÎTestClass.CylinderÖ0 method: TestClass.Cylinder :: Cylinder(double r, double h) DimensionsÌ1ÎTestClassÖ0 class: TestClass :: Dimensions DimensionsÌ128Í()ÎTestClass.DimensionsÖ0 method: TestClass.Dimensions :: Dimensions() DimensionsÌ128Í(double x, double y)ÎTestClass.DimensionsÖ0 method: TestClass.Dimensions :: Dimensions(double x, double y) MainÌ128Í()ÎTestClassÖ0Ïpublic void method: public void TestClass :: Main() SphereÌ1ÎTestClassÖ0 class: TestClass :: Sphere SphereÌ128Í(double r)ÎTestClass.SphereÖ0 method: TestClass.Sphere :: Sphere(double r) TestClassÌ1Ö0 class: TestClass piÌ8ÎTestClass.DimensionsÖ0Ïconst double field: const double TestClass.Dimensions :: pi xÌ8ÎTestClass.DimensionsÖ0Ïdouble field: double TestClass.Dimensions :: x yÌ8ÎTestClass.DimensionsÖ0Ïdouble field: double TestClass.Dimensions :: y geany-2.0/tests/ctags/masm.asm0000644000175000017500000000105114514252267013306 00000000000000.MODEL medium .DATA Msg DB "Text string" .CODE QUACK PROC PUBLIC enter 0, 0 ; May be an instruction or a macro mov bx, OFFSET DGROUP:Msg mov bx, [bp+6] mov WORD PTR [bx], ax leave ret 2 QUACK ENDP END myequ EQU 3 myequal = 4 ; http://www.xploiter.com/mirrors/asm/asm_1.htm hllequal := 4 BYTE_BUFFER LABEL BYTE WORD_BUFFER DW 512 dup (?) mov bx, ax LabelMaker1: xor ax, ax LabelMaker2: mymacro macro args endm mystruct struct ends geany-2.0/tests/ctags/internal.cs.tags0000644000175000017500000000013514514252267014751 00000000000000BaseClassÌ1Ö0 class: BaseClass IntMÌ8ÎBaseClassÖ0Ïint field: int BaseClass :: IntM geany-2.0/tests/ctags/css-comma-no-space.css0000644000175000017500000000004714514252267015752 00000000000000input,textarea{border: 1px solid red;} geany-2.0/tests/ctags/continuation.f900000644000175000017500000000024414514252267014704 00000000000000! Problem reported by Jim on 7 Jul 2002 module test real*8 :: & para_a, & ! para_a is ... para_b, & ! para_b is ... para_c ! para_c is ... geany-2.0/tests/ctags/simple.inp0000644000175000017500000000455214514252267013661 00000000000000** ** Simple input file demonstrating user material in ABAQUS ** ** This input file was created with ABAQUS/CAE, and then edited ** to insert the additional commands associated with user material. ** ** You can run the code with ** abaqus job=user_element, user=Usermat.for ** *Heading ** Job name: Job-1 Model name: Model-1 *Preprint, echo=NO, model=NO, history=NO, contact=NO ** ** PARTS ** *Part, name=Part-1 *End Part ** ** ** ASSEMBLY ** *Assembly, name=Assembly ** *Instance, name=Part-1-1, part=Part-1 *Node 1, 0., 0. 2, 2.5, 0. 3, 0., 2.5 4, 2.5, 2.5 ** ** NOTE - if you use reduced integration elements ** with a UMAT, you have to define the hourglass ** stiffness for the element ** *Element, type=CPE4R 1, 1, 2, 4, 3 *Nset, nset=_PickedSet2, internal, generate 1, 4, 1 *Elset, elset=_PickedSet2, internal 1, ** Region: (Section-1:Picked) *Elset, elset=_PickedSet2, internal 1, ** Section: Section-1 ** THE LINE BELOW WAS EDITED TO ASSIGN THE USER MATERIAL *Solid Section, elset=_PickedSet2, material=usermat_elastic 1., *hourglass stiffness 0.1 *End Instance ** *Nset, nset=_PickedSet4, internal, instance=Part-1-1 1, 2 *Elset, elset=_PickedSet4, internal, instance=Part-1-1 1, *Nset, nset=_PickedSet5, internal, instance=Part-1-1 1, 3 *Elset, elset=_PickedSet5, internal, instance=Part-1-1 1, *Nset, nset=_PickedSet6, internal, instance=Part-1-1 3, 4 *Elset, elset=_PickedSet6, internal, instance=Part-1-1 1, *End Assembly ** ** MATERIALS ** ** THE LINES BELOW WERE EDITED TO DEFINE THE USER MATERIAL *Material, name=usermat_elastic *user material, constants=2, type=mechanical 1000.0, 0.3 ** This defines the number of state variables (none in this case) *DEPVAR 1 ** ---------------------------------------------------------------- ** ** STEP: Step-1 ** *Step, name=Step-1 *Static 0.1, 1., 1e-05, 1. ** ** BOUNDARY CONDITIONS ** ** Name: BC-1 Type: Displacement/Rotation *Boundary _PickedSet4, 2, 2 ** Name: BC-2 Type: Displacement/Rotation *Boundary _PickedSet5, 1, 1 ** Name: BC-3 Type: Displacement/Rotation *Boundary _PickedSet6, 2, 2, 0.1 ** ** OUTPUT REQUESTS ** *Restart, write, frequency=0 ** ** FIELD OUTPUT: F-Output-1 ** *Output, field, variable=PRESELECT ** ** HISTORY OUTPUT: H-Output-1 ** *Output, history, variable=PRESELECT *End Stepgeany-2.0/tests/ctags/keyword_extern.cs0000644000175000017500000000057614514252267015262 00000000000000using System; using System.Runtime.InteropServices; class MyClass { [DllImport("User32.dll")] public static extern int MessageBox(int h, string m, string c, int type); public static int Main() { string myString; Console.Write("Enter your message: "); myString = Console.ReadLine(); return MessageBox(0, myString, "My Message Box", 0); } } geany-2.0/tests/ctags/bug814263.java0000644000175000017500000000014614514252267013763 00000000000000import java.util.Map; public class bug814263 { protected java.util.Map map1; protected Map map2; } geany-2.0/tests/ctags/objectivec_interface.mm.tags0000644000175000017500000000320014514252267017272 00000000000000ANOTHER_MACROÌ65536Ö0 macro: ANOTHER_MACRO A_MACRO_TESTÌ65536Ö0 macro: A_MACRO_TEST FileTreeÌ32ÎaStructÖ0 interface: aStruct :: FileTree FolderTreeÌ32Ö0 interface: FolderTree SampleTypedefObjCÌ4096Ö0 typedef: SampleTypedefObjC aStructÌ2048Ö0 struct: aStruct aStructMemberÌ8ÎaStructÖ0 field: aStruct :: aStructMember addChild:Ì128Í(FileTree*)ÎFolderTreeÖ0 method: FolderTree :: addChild:(FileTree*) anotherStructMemberÌ8ÎaStructÖ0 field: aStruct :: anotherStructMember childrenÌ8ÎFolderTreeÖ0 field: FolderTree :: children createLayoutTreeÌ128Í()ÎFileTreeÖ0 method: FileTree :: createLayoutTree() createLayoutTreeÌ128Í()ÎFolderTreeÖ0 method: FolderTree :: createLayoutTree() deallocÌ128Í()ÎFileTreeÖ0 method: FileTree :: dealloc() deallocÌ128Í()ÎFolderTreeÖ0 method: FolderTree :: dealloc() diskSizeÌ8ÎFileTreeÖ0 field: FileTree :: diskSize getDiskSizeÌ128Í()ÎFileTreeÖ0 method: FileTree :: getDiskSize() initWithName:andSize:atPlace:Ì128Í(NSString*,uint64_t,FolderTree*)ÎFileTreeÖ0 method: FileTree :: initWithName:andSize:atPlace:(NSString*,uint64_t,FolderTree*) initWithName:atPlace:Ì128Í(NSString*,FolderTree*)ÎFileTreeÖ0 method: FileTree :: initWithName:atPlace:(NSString*,FolderTree*) initWithName:atPlace:Ì128Í(NSString*,FolderTree*)ÎFolderTreeÖ0 method: FolderTree :: initWithName:atPlace:(NSString*,FolderTree*) nameÌ8ÎFileTreeÖ0 field: FileTree :: name parentÌ8ÎFileTreeÖ0 field: FileTree :: parent populateChildList:Ì128Í(NSString*)ÎFolderTreeÖ0 method: FolderTree :: populateChildList:(NSString*) representationÌ8ÎFileTreeÖ0 field: FileTree :: representation geany-2.0/tests/ctags/array_spec.f90.tags0000644000175000017500000000075314514252267015264 00000000000000Global_VariablesÌ256Ö0 namespace: Global_Variables HÌ16384ÎGlobal_VariablesÖ0 variable: Global_Variables :: H H0Ì16384ÎGlobal_VariablesÖ0 variable: Global_Variables :: H0 H1Ì16384ÎGlobal_VariablesÖ0 variable: Global_Variables :: H1 H2Ì16384ÎGlobal_VariablesÖ0 variable: Global_Variables :: H2 H3Ì16384ÎGlobal_VariablesÖ0 variable: Global_Variables :: H3 H4Ì16384ÎGlobal_VariablesÖ0 variable: Global_Variables :: H4 H5Ì16384ÎGlobal_VariablesÖ0 variable: Global_Variables :: H5 geany-2.0/tests/ctags/regexp.js0000644000175000017500000000150514514252267013503 00000000000000/* * ctags should return the following for parsing this file using: * ctags -f - simple.js * * functions: * func1 * func2 * * variables: * no_re1 * no_re2 * no_re3 * no_re4 * no_re5 * no_re6 * re1 * re2 * re3 * re4 * re5 * re6 * str1 * str2 */ var no_re1 = 1 / 2; var no_re2 = 1 + (1 + 2) / 3; var no_re3 = 1 + {0:1}[0] / 2; var no_re4 = 1 + {0:1} / 8; // gives NaN var no_re5 = "foo" / 2; // so does this var no_re6 = no_re1 / 2; var re1 = /foo/; var re2 = /\//; var re3 = /[/]/; var re4 = /'/; var re5 = /["'/]/; var re6 = /\(([a-z]*_)+/; var str1 = "a/b/c".replace(/\//g, '-'); var str2 = "Hello".replace(/O/ig, 'O'); function func1() { return /function bug1(foo){/; } function func2() { return /\(/; } geany-2.0/tests/ctags/bug1856363.py.tags0000644000175000017500000000004014514252267014510 00000000000000mainÌ16Í()Ö0 function: main() geany-2.0/tests/ctags/dotted-names.json.tags0000644000175000017500000000160114514252267016064 000000000000000Ì64Îphone.numbersÖ0 member: phone.numbers :: 0 1Ì64Îphone.numbersÖ0 member: phone.numbers :: 1 addressÌ64Ö0 member: address ageÌ64Ö0 member: age childrenÌ64Ö0 member: children cityÌ64ÎaddressÖ0 member: address :: city first.nameÌ64Ö0 member: first.name height_cmÌ64Ö0 member: height_cm is.aliveÌ64Ö0 member: is.alive last.nameÌ64Ö0 member: last.name numberÌ64Îphone.numbers.0Ö0 member: phone.numbers.0 :: number numberÌ64Îphone.numbers.1Ö0 member: phone.numbers.1 :: number phone.numbersÌ64Ö0 member: phone.numbers postal.codeÌ64ÎaddressÖ0 member: address :: postal.code spouseÌ64Ö0 member: spouse stateÌ64ÎaddressÖ0 member: address :: state street.addressÌ64ÎaddressÖ0 member: address :: street.address typeÌ64Îphone.numbers.0Ö0 member: phone.numbers.0 :: type typeÌ64Îphone.numbers.1Ö0 member: phone.numbers.1 :: type geany-2.0/tests/ctags/bug565813.f900000644000175000017500000000133014514252267013440 00000000000000module ctags_bug implicit none private save type :: foo_t integer :: bar end type foo_t integer, parameter :: N = 1000 public :: foo_t public :: foo_setbar public :: foo_set_bar public :: foo_getbar contains subroutine foo_setbar (f,b) type(foo_t), intent(out) :: f integer, intent(in) :: b f%bar = b end subroutine foo_setbar pure subroutine foo_set_bar (f,b) type(foo_t), intent(out) :: f integer, intent(in) :: b f%bar = b end subroutine foo_set_bar integer function foo_getbar (f) type(foo_t), intent(in) :: f foo_getbar = f%bar end function foo_getbar end module ctags_bug geany-2.0/tests/ctags/simple.abc.tags0000644000175000017500000000114414514252267014547 00000000000000X:0001 / T:The Ranting Highlandman.Ì64Ö0 member: X:0001 / T:The Ranting Highlandman. X:0001 / T:The Ranting Highlandman. / T:The White CockadeÌ64Ö0 member: X:0001 / T:The Ranting Highlandman. / T:The White Cockade X:0002 / T:Quick Step. 25th Regt.Ì64Ö0 member: X:0002 / T:Quick Step. 25th Regt. X:0003 / T:The Lads of the Village.Ì64Ö0 member: X:0003 / T:The Lads of the Village. X:0004 / T:I'll Touzle your Kurchy.Ì64Ö0 member: X:0004 / T:I'll Touzle your Kurchy. X:0005 / T:The Lady's play thing, or Gen Howe's March.Ì64Ö0 member: X:0005 / T:The Lady's play thing, or Gen Howe's March. geany-2.0/tests/ctags/c-trigraphs.c0000644000175000017500000000210614514252267014240 00000000000000 /* simple trigraphs */ ??=define A 1 ??=define B 2 ??=define STRINGIFY_INTERN(x) ??=x ??=define STRINGIFY(x) STRINGIFY_INTERN(x) /* doesn't expand to anything that makes sense, but as "???" is not a valid * trigraph it should not prevent "??/" to match */ ??=define D 4 ???/ #define bug1 ??=define E ?????/ #define bug2 /* \ isn't interpreted for trigraphs */ ??=define F ???\??/ extern int bug3 = ??-0; ??=define M3_INIT(a, b, c) ??< a, b, c ??> typedef int matrix3??(3??); struct str ??< char *buf; unsigned int len, size; ??>; int main(void) ??< const char *hello = STRINGIFY(hello); matrix3 m = M3_INIT(1, 2, 3); return m??(2??); ??> /* FIXME: how to test "??'" ("^"), "??!" ("|") and "??-" ("~")? * I can't think of a construct CTags cares about using those */ ??=if 0 #define bug4 ??=endif /* test the same with untaken preprocessor paths (as they are then not read by * the C parser but get.c) */ #if 0 ??=define if0d_A 1 ??=define if0d_B 2 ??=define if0d_C 4 ???/ #define bug5 ??=define I ?????/ #define bug6 ??=define I ??????????/ #define bug7 #endif geany-2.0/tests/ctags/bug726875.f90.tags0000644000175000017500000000013214514252267014403 00000000000000comaÌ65536Ö0 macro: coma combÌ65536Ö0 macro: comb comcÌ65536Ö0 macro: comc geany-2.0/tests/ctags/bit_field.c.tags0000644000175000017500000000310714514252267014675 00000000000000aÌ64Îbit_fieldsÖ0Ïunsigned int:1 member: unsigned int:1 bit_fields :: a anon_struct_1Ì2048Ö1 struct: anon_struct_1 flags: 1 bÌ64Îbit_fieldsÖ0Ïunsigned int:1 member: unsigned int:1 bit_fields :: b bad2Ì64Îbitfield_flagsÖ0ÏBYTE:1 member: BYTE:1 bitfield_flags :: bad2 bit_fieldsÌ2048Ö0 struct: bit_fields bitfield_flagsÌ2048Ö0 struct: bitfield_flags cÌ64Îbit_fieldsÖ0Ïunsigned int:2 member: unsigned int:2 bit_fields :: c expÌ64Îanon_struct_1Ö0Ïunsigned member: unsigned anon_struct_1 :: exp frac0Ì64Îanon_struct_1Ö0Ïunsigned member: unsigned anon_struct_1 :: frac0 frac1Ì64Îanon_struct_1Ö0Ïunsigned member: unsigned anon_struct_1 :: frac1 groupÌ64Îbitfield_flagsÖ0ÏBYTE:1 member: BYTE:1 bitfield_flags :: group lowerÌ64Îshortname_infoÖ0Ïunsigned char:1 member: unsigned char:1 shortname_info :: lower mystructÌ2048Ö0 struct: mystruct personalÌ64Îbitfield_flagsÖ0ÏBYTE:1 member: BYTE:1 bitfield_flags :: personal privateÌ64ÎmystructÖ0ÏBYTE member: BYTE mystruct :: private publicÌ64Îbitfield_flagsÖ0ÏBYTE:1 member: BYTE:1 bitfield_flags :: public publicÌ64ÎmystructÖ0ÏBYTE member: BYTE mystruct :: public shortname_infoÌ2048Ö0 struct: shortname_info signÌ64Îanon_struct_1Ö0Ïunsigned:1 member: unsigned:1 anon_struct_1 :: sign thatÌ64ÎmystructÖ0ÏBYTE member: BYTE mystruct :: that thisÌ64ÎmystructÖ0ÏBYTE member: BYTE mystruct :: this upperÌ64Îshortname_infoÖ0Ïunsigned char:1 member: unsigned char:1 shortname_info :: upper validÌ64Îshortname_infoÖ0Ïunsigned char:1 member: unsigned char:1 shortname_info :: valid geany-2.0/tests/ctags/css-tag-types.css0000644000175000017500000000160014514252267015064 00000000000000a foo{ color: red } a #foo{ color: red } a .foo{ color: red } a foo bar{ color: red } a foo #bar{ color: red } a foo .bar{ color: red } a #foo bar{ color: red } a #foo #bar{ color: red } a #foo .bar{ color: red } a .foo bar{ color: red } a .foo #bar{ color: red } a .foo .bar{ color: red } #a foo{ color: red } #a #foo{ color: red } #a .foo{ color: red } #a foo bar{ color: red } #a foo #bar{ color: red } #a foo .bar{ color: red } #a #foo bar{ color: red } #a #foo #bar{ color: red } #a #foo .bar{ color: red } #a .foo bar{ color: red } #a .foo #bar{ color: red } #a .foo .bar{ color: red } .a foo{ color: red } .a #foo{ color: red } .a .foo{ color: red } .a foo bar{ color: red } .a foo #bar{ color: red } .a foo .bar{ color: red } .a #foo bar{ color: red } .a #foo #bar{ color: red } .a #foo .bar{ color: red } .a .foo bar{ color: red } .a .foo #bar{ color: red } .a .foo .bar{ color: red } geany-2.0/tests/ctags/simple.md0000644000175000017500000000035414514252267013467 00000000000000# a ## b ### c #### d ##### e ###### f # g # # h ## ## i # ## j ## ## k ### ### l # ### m ## ### n ### ### o ### #### p # #### q ##### ##### r # ##### s ###### ###### t # ###### u ####### A = B == C === D - E -- F --- geany-2.0/tests/ctags/make-target-with-parentheses.mak0000644000175000017500000000003514514252267020033 00000000000000$(obj)/raid6int1.c: F := 6 geany-2.0/tests/ctags/bug1111214.v0000644000175000017500000000117614514252267013356 00000000000000// File example.v // // Below is an example of a comment that is mis-parsed by exuberant ctags. // It uses the multi-line comment format, i.e. /* ... */ except that in // this case, the character sequence immediately preceding the closing // delimiter is an asterisk. (Any even number of asterisks would have the // same problem. // The line immediately afterwards is used to demonstrate the problem. // the module name 'wahoo' isn't recognised, because the parser mistakenly // thinks we are still in a multi-line comment. /* * I am a multi-line comment * I happen to end in a strange * (but legal) way: **/ module wahoo () begin end geany-2.0/tests/ctags/bug1777344.java.tags0000644000175000017500000000103114514252267015003 00000000000000VÌ128Í()Îbug1777344Ö0Ï method: bug1777344 :: V() bÌ8Îbug1777344Ö0Ïboolean field: boolean bug1777344 :: b bug1777344Ì1Ö0 class: bug1777344 cÌ8Îbug1777344Ö0Ïboolean field: boolean bug1777344 :: c dÌ8Îbug1777344Ö0Ïboolean field: boolean bug1777344 :: d eÌ8Îbug1777344Ö0Ïboolean field: boolean bug1777344 :: e map1Ì8Îbug1777344Ö0ÏHashMap field: HashMap bug1777344 :: map1 map2Ì8Îbug1777344Ö0ÏHashMap field: HashMap bug1777344 :: map2 map3Ì8Îbug1777344Ö0ÏHashMap field: HashMap bug1777344 :: map3 geany-2.0/tests/ctags/simple.diff.tags0000644000175000017500000000041014514252267014725 00000000000000a/Units/review-needed.r/simple.ksh.t/expected.tagsÌ16Ö0 function: a/Units/review-needed.r/simple.ksh.t/expected.tags a/main/parsers.hÌ16Ö0 function: a/main/parsers.h a/source.makÌ16Ö0 function: a/source.mak b/parsers/diff.cÌ16Ö0 function: b/parsers/diff.c geany-2.0/tests/ctags/parenthesis-rvalue.js.tags0000644000175000017500000000126614514252267016773 00000000000000aÌ64Îd1Ö0 member: d1 :: a aÌ64Îd2Ö0 member: d2 :: a a1Ì16384Ö0 variable: a1 a2Ì16384Ö0 variable: a2 bÌ64Îd1Ö0 member: d1 :: b bÌ64Îd2Ö0 member: d2 :: b b1Ì16Í()Ö0 function: b1() b1subÌ16Í()Îb1Ö0 function: b1 :: b1sub() b2Ì16Í()Ö0 function: b2() b2subÌ16Í()Îb2Ö0 function: b2 :: b2sub() b3Ì16Í()Ö0 function: b3() b3subÌ16Í()Îb3Ö0 function: b3 :: b3sub() c1Ì16384Ö0 variable: c1 c2Ì16384Ö0 variable: c2 d1Ì1Ö0 class: d1 d2Ì1Ö0 class: d2 e1Ì16Í()Ö0 function: e1() e1subÌ16Í()Îe1Ö0 function: e1 :: e1sub() e2Ì16Í()Ö0 function: e2() e2subÌ16Í()Îe2Ö0 function: e2 :: e2sub() e3Ì16Í()Ö0 function: e3() e3subÌ16Í()Îe3Ö0 function: e3 :: e3sub() geany-2.0/tests/ctags/vhdl-type.vhd.tags0000644000175000017500000002202114514252267015223 00000000000000CFG_IRQ_ETHMACÌ16384Îtypes_miscÖ0 variable: types_misc :: CFG_IRQ_ETHMAC CFG_IRQ_GNSSENGINEÌ16384Îtypes_miscÖ0 variable: types_misc :: CFG_IRQ_GNSSENGINE CFG_IRQ_GPTIMERSÌ16384Îtypes_miscÖ0 variable: types_misc :: CFG_IRQ_GPTIMERS CFG_IRQ_TOTALÌ16384Îtypes_miscÖ0 variable: types_misc :: CFG_IRQ_TOTAL CFG_IRQ_UART1Ì16384Îtypes_miscÖ0 variable: types_misc :: CFG_IRQ_UART1 CFG_IRQ_UNUSEDÌ16384Îtypes_miscÖ0 variable: types_misc :: CFG_IRQ_UNUSED adc_clkÌ16384Îtypes_misc.axi4_pnpÖ0 variable: types_misc.axi4_pnp :: adc_clk axi4_flashspiÌ64Îtypes_miscÖ0 member: types_misc :: axi4_flashspi axi4_gpioÌ64Îtypes_miscÖ0 member: types_misc :: axi4_gpio axi4_gptimersÌ64Îtypes_miscÖ0 member: types_misc :: axi4_gptimers axi4_irqctrlÌ64Îtypes_miscÖ0 member: types_misc :: axi4_irqctrl axi4_otpÌ64Îtypes_miscÖ0 member: types_misc :: axi4_otp axi4_pnpÌ64Îtypes_miscÖ0 member: types_misc :: axi4_pnp axi4_romÌ64Îtypes_miscÖ0 member: types_misc :: axi4_rom axi4_sramÌ64Îtypes_miscÖ0 member: types_misc :: axi4_sram axi4_uartÌ64Îtypes_miscÖ0 member: types_misc :: axi4_uart cfgÌ16384Îtypes_misc.axi4_flashspiÖ0 variable: types_misc.axi4_flashspi :: cfg cfgÌ16384Îtypes_misc.axi4_gpioÖ0 variable: types_misc.axi4_gpio :: cfg cfgÌ16384Îtypes_misc.axi4_gptimersÖ0 variable: types_misc.axi4_gptimers :: cfg cfgÌ16384Îtypes_misc.axi4_otpÖ0 variable: types_misc.axi4_otp :: cfg cfgÌ16384Îtypes_misc.axi4_pnpÖ0 variable: types_misc.axi4_pnp :: cfg cfgÌ16384Îtypes_misc.axi4_romÖ0 variable: types_misc.axi4_rom :: cfg cfgÌ16384Îtypes_misc.axi4_sramÖ0 variable: types_misc.axi4_sram :: cfg cfgÌ16384Îtypes_misc.axi4_uartÖ0 variable: types_misc.axi4_uart :: cfg clkÌ16384Îtypes_misc.axi4_flashspiÖ0 variable: types_misc.axi4_flashspi :: clk clkÌ16384Îtypes_misc.axi4_gpioÖ0 variable: types_misc.axi4_gpio :: clk clkÌ16384Îtypes_misc.axi4_gptimersÖ0 variable: types_misc.axi4_gptimers :: clk clkÌ16384Îtypes_misc.axi4_irqctrlÖ0 variable: types_misc.axi4_irqctrl :: clk clkÌ16384Îtypes_misc.axi4_otpÖ0 variable: types_misc.axi4_otp :: clk clkÌ16384Îtypes_misc.axi4_romÖ0 variable: types_misc.axi4_rom :: clk clkÌ16384Îtypes_misc.axi4_sramÖ0 variable: types_misc.axi4_sram :: clk clkÌ16384Îtypes_misc.axi4_uartÖ0 variable: types_misc.axi4_uart :: clk clkÌ16384Îtypes_misc.tap_jtagÖ0 variable: types_misc.tap_jtag :: clk clkÌ16384Îtypes_misc.uart_tapÖ0 variable: types_misc.uart_tap :: clk iÌ16384Îtypes_misc.axi4_gpioÖ0 variable: types_misc.axi4_gpio :: i iÌ16384Îtypes_misc.axi4_pnpÖ0 variable: types_misc.axi4_pnp :: i iÌ16384Îtypes_misc.axi4_romÖ0 variable: types_misc.axi4_rom :: i iÌ16384Îtypes_misc.axi4_sramÖ0 variable: types_misc.axi4_sram :: i i_axiÌ16384Îtypes_misc.axi4_flashspiÖ0 variable: types_misc.axi4_flashspi :: i_axi i_axiÌ16384Îtypes_misc.axi4_gptimersÖ0 variable: types_misc.axi4_gptimers :: i_axi i_axiÌ16384Îtypes_misc.axi4_irqctrlÖ0 variable: types_misc.axi4_irqctrl :: i_axi i_axiÌ16384Îtypes_misc.axi4_otpÖ0 variable: types_misc.axi4_otp :: i_axi i_axiÌ16384Îtypes_misc.axi4_uartÖ0 variable: types_misc.axi4_uart :: i_axi i_cfg_rsetupÌ16384Îtypes_misc.axi4_otpÖ0 variable: types_misc.axi4_otp :: i_cfg_rsetup i_cfg_wactiveÌ16384Îtypes_misc.axi4_otpÖ0 variable: types_misc.axi4_otp :: i_cfg_wactive i_cfg_wadrsetupÌ16384Îtypes_misc.axi4_otpÖ0 variable: types_misc.axi4_otp :: i_cfg_wadrsetup i_cfg_wholdÌ16384Îtypes_misc.axi4_otpÖ0 variable: types_misc.axi4_otp :: i_cfg_whold i_gpioÌ16384Îtypes_misc.axi4_gpioÖ0 variable: types_misc.axi4_gpio :: i_gpio i_irqsÌ16384Îtypes_misc.axi4_irqctrlÖ0 variable: types_misc.axi4_irqctrl :: i_irqs i_mstiÌ16384Îtypes_misc.tap_jtagÖ0 variable: types_misc.tap_jtag :: i_msti i_mstiÌ16384Îtypes_misc.uart_tapÖ0 variable: types_misc.uart_tap :: i_msti i_ntrstÌ16384Îtypes_misc.tap_jtagÖ0 variable: types_misc.tap_jtag :: i_ntrst i_otp_busyÌ16384Îtypes_misc.axi4_pnpÖ0 variable: types_misc.axi4_pnp :: i_otp_busy i_otp_rdataÌ16384Îtypes_misc.axi4_otpÖ0 variable: types_misc.axi4_otp :: i_otp_rdata i_spiÌ16384Îtypes_misc.axi4_flashspiÖ0 variable: types_misc.axi4_flashspi :: i_spi i_tckÌ16384Îtypes_misc.tap_jtagÖ0 variable: types_misc.tap_jtag :: i_tck i_tdiÌ16384Îtypes_misc.tap_jtagÖ0 variable: types_misc.tap_jtag :: i_tdi i_tmsÌ16384Îtypes_misc.tap_jtagÖ0 variable: types_misc.tap_jtag :: i_tms i_uartÌ16384Îtypes_misc.axi4_uartÖ0 variable: types_misc.axi4_uart :: i_uart i_uartÌ16384Îtypes_misc.uart_tapÖ0 variable: types_misc.uart_tap :: i_uart inSysClkÌ16384Îtypes_misc.reset_globalÖ0 variable: types_misc.reset_global :: inSysClk inSysResetÌ16384Îtypes_misc.reset_globalÖ0 variable: types_misc.reset_global :: inSysReset mstcfgÌ16384Îtypes_misc.axi4_pnpÖ0 variable: types_misc.axi4_pnp :: mstcfg nrstÌ16384Îtypes_misc.axi4_flashspiÖ0 variable: types_misc.axi4_flashspi :: nrst nrstÌ16384Îtypes_misc.axi4_gpioÖ0 variable: types_misc.axi4_gpio :: nrst nrstÌ16384Îtypes_misc.axi4_gptimersÖ0 variable: types_misc.axi4_gptimers :: nrst nrstÌ16384Îtypes_misc.axi4_irqctrlÖ0 variable: types_misc.axi4_irqctrl :: nrst nrstÌ16384Îtypes_misc.axi4_otpÖ0 variable: types_misc.axi4_otp :: nrst nrstÌ16384Îtypes_misc.axi4_pnpÖ0 variable: types_misc.axi4_pnp :: nrst nrstÌ16384Îtypes_misc.axi4_romÖ0 variable: types_misc.axi4_rom :: nrst nrstÌ16384Îtypes_misc.axi4_sramÖ0 variable: types_misc.axi4_sram :: nrst nrstÌ16384Îtypes_misc.axi4_uartÖ0 variable: types_misc.axi4_uart :: nrst nrstÌ16384Îtypes_misc.tap_jtagÖ0 variable: types_misc.tap_jtag :: nrst nrstÌ16384Îtypes_misc.uart_tapÖ0 variable: types_misc.uart_tap :: nrst oÌ16384Îtypes_misc.axi4_gpioÖ0 variable: types_misc.axi4_gpio :: o oÌ16384Îtypes_misc.axi4_pnpÖ0 variable: types_misc.axi4_pnp :: o oÌ16384Îtypes_misc.axi4_romÖ0 variable: types_misc.axi4_rom :: o oÌ16384Îtypes_misc.axi4_sramÖ0 variable: types_misc.axi4_sram :: o o_axiÌ16384Îtypes_misc.axi4_flashspiÖ0 variable: types_misc.axi4_flashspi :: o_axi o_axiÌ16384Îtypes_misc.axi4_gptimersÖ0 variable: types_misc.axi4_gptimers :: o_axi o_axiÌ16384Îtypes_misc.axi4_irqctrlÖ0 variable: types_misc.axi4_irqctrl :: o_axi o_axiÌ16384Îtypes_misc.axi4_otpÖ0 variable: types_misc.axi4_otp :: o_axi o_axiÌ16384Îtypes_misc.axi4_uartÖ0 variable: types_misc.axi4_uart :: o_axi o_busyÌ16384Îtypes_misc.axi4_otpÖ0 variable: types_misc.axi4_otp :: o_busy o_cfgÌ16384Îtypes_misc.axi4_irqctrlÖ0 variable: types_misc.axi4_irqctrl :: o_cfg o_gpioÌ16384Îtypes_misc.axi4_gpioÖ0 variable: types_misc.axi4_gpio :: o_gpio o_gpio_dirÌ16384Îtypes_misc.axi4_gpioÖ0 variable: types_misc.axi4_gpio :: o_gpio_dir o_irqÌ16384Îtypes_misc.axi4_gptimersÖ0 variable: types_misc.axi4_gptimers :: o_irq o_irqÌ16384Îtypes_misc.axi4_uartÖ0 variable: types_misc.axi4_uart :: o_irq o_irq_meipÌ16384Îtypes_misc.axi4_irqctrlÖ0 variable: types_misc.axi4_irqctrl :: o_irq_meip o_jtag_vrefÌ16384Îtypes_misc.tap_jtagÖ0 variable: types_misc.tap_jtag :: o_jtag_vref o_mstcfgÌ16384Îtypes_misc.tap_jtagÖ0 variable: types_misc.tap_jtag :: o_mstcfg o_mstcfgÌ16384Îtypes_misc.uart_tapÖ0 variable: types_misc.uart_tap :: o_mstcfg o_mstoÌ16384Îtypes_misc.tap_jtagÖ0 variable: types_misc.tap_jtag :: o_msto o_mstoÌ16384Îtypes_misc.uart_tapÖ0 variable: types_misc.uart_tap :: o_msto o_otp_addrÌ16384Îtypes_misc.axi4_otpÖ0 variable: types_misc.axi4_otp :: o_otp_addr o_otp_cfg_rsetupÌ16384Îtypes_misc.axi4_pnpÖ0 variable: types_misc.axi4_pnp :: o_otp_cfg_rsetup o_otp_cfg_wactiveÌ16384Îtypes_misc.axi4_pnpÖ0 variable: types_misc.axi4_pnp :: o_otp_cfg_wactive o_otp_cfg_wadrsetupÌ16384Îtypes_misc.axi4_pnpÖ0 variable: types_misc.axi4_pnp :: o_otp_cfg_wadrsetup o_otp_cfg_wholdÌ16384Îtypes_misc.axi4_pnpÖ0 variable: types_misc.axi4_pnp :: o_otp_cfg_whold o_otp_reÌ16384Îtypes_misc.axi4_otpÖ0 variable: types_misc.axi4_otp :: o_otp_re o_otp_wdataÌ16384Îtypes_misc.axi4_otpÖ0 variable: types_misc.axi4_otp :: o_otp_wdata o_otp_weÌ16384Îtypes_misc.axi4_otpÖ0 variable: types_misc.axi4_otp :: o_otp_we o_pwmÌ16384Îtypes_misc.axi4_gptimersÖ0 variable: types_misc.axi4_gptimers :: o_pwm o_spiÌ16384Îtypes_misc.axi4_flashspiÖ0 variable: types_misc.axi4_flashspi :: o_spi o_tdoÌ16384Îtypes_misc.tap_jtagÖ0 variable: types_misc.tap_jtag :: o_tdo o_uartÌ16384Îtypes_misc.axi4_uartÖ0 variable: types_misc.axi4_uart :: o_uart o_uartÌ16384Îtypes_misc.uart_tapÖ0 variable: types_misc.uart_tap :: o_uart outResetÌ16384Îtypes_misc.reset_globalÖ0 variable: types_misc.reset_global :: outReset reset_globalÌ64Îtypes_miscÖ0 member: types_misc :: reset_global slvcfgÌ16384Îtypes_misc.axi4_pnpÖ0 variable: types_misc.axi4_pnp :: slvcfg spi_in_typeÌ4096Îtypes_miscÖ0 typedef: types_misc :: spi_in_type spi_out_noneÌ16384Îtypes_miscÖ0 variable: types_misc :: spi_out_none spi_out_typeÌ4096Îtypes_miscÖ0 typedef: types_misc :: spi_out_type sys_clkÌ16384Îtypes_misc.axi4_pnpÖ0 variable: types_misc.axi4_pnp :: sys_clk tap_jtagÌ64Îtypes_miscÖ0 member: types_misc :: tap_jtag types_miscÌ256Ö0 namespace: types_misc uart_in_typeÌ4096Îtypes_miscÖ0 typedef: types_misc :: uart_in_type uart_out_typeÌ4096Îtypes_miscÖ0 typedef: types_misc :: uart_out_type uart_tapÌ64Îtypes_miscÖ0 member: types_misc :: uart_tap geany-2.0/tests/ctags/css-simple.css.tags0000644000175000017500000000050214514252267015375 00000000000000#footerÌ16384Ö0 variable: #footer *Ì2048Ö0 struct: * .foo aÌ2048Ö0 struct: .foo a .foo bÌ2048Ö0 struct: .foo b .headerÌ1Ö0 class: .header .redÌ1Ö0 class: .red div.magicÌ1Ö0 class: div.magic htmlÌ2048Ö0 struct: html ul > li > aÌ2048Ö0 struct: ul > li > a ul liÌ2048Ö0 struct: ul li geany-2.0/tests/ctags/matlab_test.m.tags0000644000175000017500000000022114514252267015257 00000000000000func1Ì16Ö0 function: func1 func2Ì16Ö0 function: func2 func3Ì16Ö0 function: func3 func4Ì16Ö0 function: func4 func5Ì16Ö0 function: func5 geany-2.0/tests/ctags/bug507864.c.tags0000644000175000017500000000033214514252267014224 00000000000000func1Ì16Í(ENTSEQNO (seq))Ö0ÏFUNCSTS function: FUNCSTS func1(ENTSEQNO (seq)) func2Ì16Í(MEMTXT (form_msg),MEMTXT (text),MEMTXT (mail))Ö0ÏFUNCSTS function: FUNCSTS func2(MEMTXT (form_msg),MEMTXT (text),MEMTXT (mail)) geany-2.0/tests/ctags/bug842077.pl0000644000175000017500000000152514514252267013463 00000000000000# Bugs item #842077, was opened at 2003-11-14 10:57 # Message generated for change (Tracker Item Submitted) made by Item Submitter # You can respond by visiting: # https://sourceforge.net/tracker/?func=detail&atid=106556&aid=842077&group_id=6556 # Category: None # Group: None # Status: Open # Resolution: None # Priority: 5 # Submitted By: Christian Reis (kiko_async) # Assigned to: Nobody/Anonymous (nobody) # Summary: wrong precedence applied to perl POD and "here document" # Initial Comment: # Basically, ctags stops parsing when it reaches code # with the syntax below: # ... $this->print_log(< * To: ctags-users@lists.sourceforge.net * Subject: [Ctags] seeking for help to set ctags to work with old FORTRAN * * Hi * * I'm trying to set ctags to work with some old FORTRAN 77 programs. * I'm in Windows 2000, vim 6.1 and exuberant ctags 5.3.1. * The programs are for VAX FORTRAN 77 as of 1988. Written with tabs and 132 columns line length. * * [...] * * What am I doing wrong? This is my first contact with tags files of any sort and I'm vexed. * * A sample .DES file is included at the bottom. * * TIA * * Juan Lanus * TECNOSOL * Argentina * * **************** ********************************************************************* * * * Sistema Personalizado - descripcion de registros - CGA - 1/12/89 * * * * De tablas generales PERTAB012 - tabla 010 * * * ********************************************************************* character*6 FEC010 !Fecha de Proceso aa/mm/dd character*5 URE010 !Ultimo Numero de Pedido character*5 REM010 !Ultimo Numero de Remito character*5 FAC010 !Ultimo Numero de Factura character*40 PER010 !Registro de Fecha equivalence (PER010(1:1) ,FEC010(1:1)) equivalence (PER010(7:7) ,URE010(1:1)) equivalence (PER010(12:12),REM010(1:1)) equivalence (PER010(17:17),FAC010(1:1)) ****************** Fin Registro de Fecha *********************************** geany-2.0/tests/ctags/css-comma-no-space.css.tags0000644000175000017500000000010414514252267016701 00000000000000inputÌ2048Ö0 struct: input textareaÌ2048Ö0 struct: textarea geany-2.0/tests/ctags/events.cs.tags0000644000175000017500000000315414514252267014445 00000000000000AddÌ128Í(object value)ÎMyCollections.ListWithChangedEventÖ0Ïpublic override int method: public override int MyCollections.ListWithChangedEvent :: Add(object value) ChangedEventHandlerÌ128Í(object sender, EventArgs e)ÎMyCollectionsÖ0Ïpublic delegate void method: public delegate void MyCollections :: ChangedEventHandler(object sender, EventArgs e) ClearÌ128Í()ÎMyCollections.ListWithChangedEventÖ0Ïpublic override void method: public override void MyCollections.ListWithChangedEvent :: Clear() DetachÌ128Í()ÎTestEvents.EventListenerÖ0Ïpublic void method: public void TestEvents.EventListener :: Detach() EventListenerÌ1ÎTestEventsÖ0 class: TestEvents :: EventListener EventListenerÌ128Í(ListWithChangedEvent list)ÎTestEvents.EventListenerÖ0 method: TestEvents.EventListener :: EventListener(ListWithChangedEvent list) ListÌ8ÎTestEvents.EventListenerÖ0ÏListWithChangedEvent field: ListWithChangedEvent TestEvents.EventListener :: List ListChangedÌ128Í(object sender, EventArgs e)ÎTestEvents.EventListenerÖ0Ïprivate void method: private void TestEvents.EventListener :: ListChanged(object sender, EventArgs e) ListWithChangedEventÌ1ÎMyCollectionsÖ0 class: MyCollections :: ListWithChangedEvent MainÌ128Í()ÎTestEvents.TestÖ0Ïpublic void method: public void TestEvents.Test :: Main() MyCollectionsÌ256Ö0 namespace: MyCollections OnChangedÌ128Í(EventArgs e)ÎMyCollections.ListWithChangedEventÖ0Ïprotected virtual void method: protected virtual void MyCollections.ListWithChangedEvent :: OnChanged(EventArgs e) TestÌ1ÎTestEventsÖ0 class: TestEvents :: Test TestEventsÌ256Ö0 namespace: TestEvents geany-2.0/tests/ctags/simple.ps1.tags0000644000175000017500000000163414514252267014531 00000000000000A-Global-Scope-FunctionÌ16Í()Ö0 function: A-Global-Scope-Function() ALocalVarÌ16384Ö0 variable: ALocalVar BasePathÌ16384Ö0 variable: BasePath ErrorActionPreferenceÌ16384Ö0 variable: ErrorActionPreference LoadTemplateÌ16Í($template)Ö0 function: LoadTemplate($template) LogMessageÌ16Í()Ö0 function: LogMessage() LogMessageOKÌ16Í()Ö0 function: LogMessageOK() MainÌ16Í()Ö0 function: Main() MyFilterÌ16Ö0 function: MyFilter MyPrivateFilterÌ16Ö0 function: MyPrivateFilter Read-Configuration-FileÌ16Í()Ö0 function: Read-Configuration-File() SecondLevelNestedFunctionÌ16Í()ÎTopLevelFunctionÖ0 function: TopLevelFunction :: SecondLevelNestedFunction() SettingsÌ16384Ö0 variable: Settings ThirdLevelNestedFunctionÌ16Í()ÎTopLevelFunction::SecondLevelNestedFunctionÖ0 function: TopLevelFunction::SecondLevelNestedFunction :: ThirdLevelNestedFunction() TopLevelFunctionÌ16Í()Ö0 function: TopLevelFunction() geany-2.0/tests/ctags/ada-adb.adb.tags0000644000175000017500000000157314514252267014536 00000000000000AltivecÌ16Ö0 function: Altivec DaysÌ4096ÎGreetÖ0 typedef: Greet :: Days FridayÌ4ÎDaysÖ0 enumerator: Days :: Friday GreetÌ16Ö0 function: Greet MÌ16384ÎGreetÖ0 variable: Greet :: M MondayÌ4ÎDaysÖ0 enumerator: Days :: Monday SÌ16384ÎGreetÖ0 variable: Greet :: S SaturdayÌ4ÎDaysÖ0 enumerator: Days :: Saturday SundayÌ4ÎDaysÖ0 enumerator: Days :: Sunday ThursdayÌ4ÎDaysÖ0 enumerator: Days :: Thursday TuesdayÌ4ÎDaysÖ0 enumerator: Days :: Tuesday Vector_AÌ65536ÎAltivecÖ0 macro: Altivec :: Vector_A Vector_BÌ65536ÎAltivecÖ0 macro: Altivec :: Vector_B Vector_CÌ16384ÎAltivecÖ0 variable: Altivec :: Vector_C View_AÌ65536ÎAltivecÖ0 macro: Altivec :: View_A View_BÌ65536ÎAltivecÖ0 macro: Altivec :: View_B View_CÌ16384ÎAltivecÖ0 variable: Altivec :: View_C WednesdayÌ4ÎDaysÖ0 enumerator: Days :: Wednesday Weekend_DaysÌ4096ÎGreetÖ0 typedef: Greet :: Weekend_Days geany-2.0/tests/ctags/static_array.c0000644000175000017500000000015514514252267014504 00000000000000/* Demonstrates temporary bug caused by statement reinitialization */ static wchar_t charset2uni[256] = { }; geany-2.0/tests/ctags/preprocessor.f900000644000175000017500000000036614514252267014725 00000000000000#include ! preprocessor directives on line 1 (and only line 1) cause breakage module Invisible integer :: nope contains function SpillsOutside ! ... end function SpillsOutside end module Invisible program Main ! ... end program Main geany-2.0/tests/ctags/char-selector.f900000644000175000017500000000104314514252267014723 00000000000000! Test for bug in parsing of char-selector MODULE OUT_RD5 USE inmdmx IMPLICIT NONE SAVE CHARACTER*(MXPATHLNGTH) temp PRIVATE :: temp INTEGER(4), PRIVATE, PARAMETER :: MXDDI=45 CHARACTER*40 titles(MXDDI) PRIVATE :: titles CHARACTER*12 units(MXDDI) PRIVATE :: units INTEGER(4), PRIVATE, DIMENSION (MXDDI+1) :: list CHARACTER(1024) :: fpshape INTEGER(4), PRIVATE :: nout CHARACTER*(1024) :: fpshape2 INTEGER(4), PRIVATE :: last END MODULE OUT_RD5 geany-2.0/tests/ctags/keyword_abstract.cs.tags0000644000175000017500000000071014514252267016503 00000000000000MainÌ128Í()ÎMyDerivedCÖ0Ïpublic void method: public void MyDerivedC :: Main() MyBaseCÌ1Ö0 class: MyBaseC MyDerivedCÌ1Ö0 class: MyDerivedC MyMethodÌ128Í()ÎMyBaseCÖ0Ïpublic abstract void method: public abstract void MyBaseC :: MyMethod() MyMethodÌ128Í()ÎMyDerivedCÖ0Ïpublic override void method: public override void MyDerivedC :: MyMethod() xÌ8ÎMyBaseCÖ0Ïint field: int MyBaseC :: x yÌ8ÎMyBaseCÖ0Ïint field: int MyBaseC :: y geany-2.0/tests/ctags/objectivec_implementation.mm.tags0000644000175000017500000000212214514252267020361 00000000000000addChild:Ì128Í(FileTree*)ÎFolderTreeÖ0 method: FolderTree :: addChild:(FileTree*) createFileList:atPlace:Ì1Í(NSString*,FolderTree*)ÎFolderTreeÖ0 class: FolderTree :: createFileList:atPlace:(NSString*,FolderTree*) createLayoutTreeÌ128Í()ÎFileTreeÖ0 method: FileTree :: createLayoutTree() createLayoutTreeÌ128Í()ÎFolderTreeÖ0 method: FolderTree :: createLayoutTree() deallocÌ128Í()ÎFileTreeÖ0 method: FileTree :: dealloc() deallocÌ128Í()ÎFolderTreeÖ0 method: FolderTree :: dealloc() getDiskSizeÌ128Í()ÎFileTreeÖ0 method: FileTree :: getDiskSize() initWithName:andSize:atPlace:Ì128Í(NSString*,FileSize,FolderTree*)ÎFileTreeÖ0 method: FileTree :: initWithName:andSize:atPlace:(NSString*,FileSize,FolderTree*) initWithName:atPlace:Ì128Í(NSString*,FolderTree*)ÎFileTreeÖ0 method: FileTree :: initWithName:atPlace:(NSString*,FolderTree*) initWithName:atPlace:Ì128Í(NSString*,FolderTree*)ÎFolderTreeÖ0 method: FolderTree :: initWithName:atPlace:(NSString*,FolderTree*) populateChildList:Ì128Í(NSString*)ÎFolderTreeÖ0 method: FolderTree :: populateChildList:(NSString*) geany-2.0/tests/ctags/keyword_implicit.cs0000644000175000017500000000106014514252267015554 00000000000000// cs_keyword_implicit.cs using System; struct Digit { byte value; public Digit(byte value) { if (value < 0 || value > 9) throw new ArgumentException(); this.value = value; } // define implicit Digit-to-byte conversion operator: public static implicit operator byte(Digit d) { Console.WriteLine( "conversion occurred" ); return d.value; } } class Test { public static void Main() { Digit d = new Digit(3); // implicit (no cast) conversion from Digit to byte byte b = d; } } geany-2.0/tests/ctags/bracematch.js.tags0000644000175000017500000000056614514252267015245 00000000000000ContainerÌ16Í()Ö0 function: Container() MyClassÌ1Ö0 class: MyClass insertÌ128Í(element, insertions)ÎMyClassÖ0 method: MyClass :: insert(element, insertions) wrapÌ128Í(element, wrapper, attributes)ÎMyClassÖ0 method: MyClass :: wrap(element, wrapper, attributes) xÌ16Í()ÎContainerÖ0 function: Container :: x() yÌ16Í()ÎContainerÖ0 function: Container :: y() geany-2.0/tests/ctags/complex-return.js0000644000175000017500000000167414514252267015204 00000000000000 function func1() { return { a: 1, b:2 }; } function func2() { return 42; } var class1 = function() { this.method1 = function() { return 42; }; this.method2 = function() { return { a:1, b:2 }; }; this.method3 = function() { return [1, 2, 3]; }; this.method4 = function() { return "hello"; }; }; var class2 = function() { this.c2m1 = function() { c2m3(function() { return { 'test': {} }; }); }; this.c2m2 = function(f) { return { 'ret': f() }; }; this.c2m3 = function(f) { return f(); }; }; var class3 = function() { this.c3m1 = function() { return function(n) { if (n == 42) { return 0; } else { return (n + 1) % 42; } }; }; this.c3m2 = function() { return 0; }; } var class4 = function() { this.method1 = function() { return [{a:1, b:2}, {a:3, b:4}, {a:5, b:6}]; }; this.method2 = function() { return 0; }; }; geany-2.0/tests/ctags/bug1950327.js0000644000175000017500000000206214514252267013540 00000000000000// I've attached the simple test case as bugDemo.js. Trigger the bug by // uncommenting line 8. Attached are tags files with line 21 commented/not // commented. This is the current tip, svn r663. // // When the container.dirtyTab line is uncommented you see these methods: // TabChrome.createTabTile // TabChrome.init // // When the container.dirtyTab line is commented you see these methods: // TabChrome.createTabTile // TabChrome.destroyTabTile // TabChrome.init // TabChrome.prototype = { init: function() { this.browserMap = new Object(); }, createTabTile: function(browser) { //container.dirtyTab = {'url': false, 'title':false, 'snapshot':false, '*': false} return container; }, destroyTabTile: function(tile) { } } Different.prototype = { init: function() { this.browserMap = new Object(); }, createTabTile: function(browser) { container.dirtyTab = {'url': false, 'title':false, 'snapshot':false, '*': false} return container; }, destroyTabTile: function(tile) { } } geany-2.0/tests/ctags/size_t_wchar_t_typedef.c.tags0000644000175000017500000000012414514252267017474 00000000000000size_tÌ4096Ö0Ïint typedef: int size_t wchar_tÌ4096Ö0Ïint typedef: int wchar_t geany-2.0/tests/ctags/ada-overriding.ads.tags0000644000175000017500000000020414514252267016167 00000000000000InputÌ512Ö0 package: Input InutileÌ1024ÎInputÖ0 prototype: Input :: Inutile Tasche_TÌ1024ÎInputÖ0 prototype: Input :: Tasche_T geany-2.0/tests/ctags/bug1944150.sql.tags0000644000175000017500000000015514514252267014656 00000000000000tr_d_cash_trade_commentÌ65536Îcash_trade_commentÖ0 macro: cash_trade_comment :: tr_d_cash_trade_comment geany-2.0/tests/ctags/bug1743330.v0000644000175000017500000000024414514252267013363 00000000000000// somewhat contrived, but i came across a real-life file that caused this // crash. value= hello/ world; // dummy stuff to generate a tag module dummy; endmodule geany-2.0/tests/ctags/value.f0000644000175000017500000000024714514252267013140 00000000000000! Provided by Brian Helsinki, 7 March 2003 program figure(aa) REAL aa VALUE aa ! not supported breaks fig; pass by value integer fig call fig2(aa) RETURN END geany-2.0/tests/ctags/simple.lisp.tags0000644000175000017500000000034614514252267014774 00000000000000A1Ì16Ö0 function: A1 B1Ì16384Ö0 variable: B1 C1Ì8Ö0 field: C1 DEFUNKNOWN1Ì65536Ö0 macro: DEFUNKNOWN1 a0Ì16Ö0 function: a0 b0Ì16384Ö0 variable: b0 c0Ì8Ö0 field: c0 defunknown0Ì65536Ö0 macro: defunknown0 geany-2.0/tests/ctags/test.py.tags0000644000175000017500000000013214514252267014134 00000000000000mainÌ16Í()Ö0 function: main() varÌ16384Ö0 variable: var var2Ì16384Ö0 variable: var2 geany-2.0/tests/ctags/keyword_enum.cs.tags0000644000175000017500000000130314514252267015643 00000000000000DaysÌ2ÎEnumTestÖ0 enum: EnumTest :: Days EnumTestÌ1Ö0 class: EnumTest FriÌ4ÎEnumTest.DaysÖ0 enumerator: EnumTest.Days :: Fri MainÌ128Í()ÎEnumTestÖ0Ïpublic void method: public void EnumTest :: Main() MaxÌ4ÎEnumTest.RangeÖ0 enumerator: EnumTest.Range :: Max MinÌ4ÎEnumTest.RangeÖ0 enumerator: EnumTest.Range :: Min MonÌ4ÎEnumTest.DaysÖ0 enumerator: EnumTest.Days :: Mon RangeÌ2ÎEnumTestÖ0 enum: EnumTest :: Range SatÌ4ÎEnumTest.DaysÖ0 enumerator: EnumTest.Days :: Sat SunÌ4ÎEnumTest.DaysÖ0 enumerator: EnumTest.Days :: Sun ThuÌ4ÎEnumTest.DaysÖ0 enumerator: EnumTest.Days :: Thu TueÌ4ÎEnumTest.DaysÖ0 enumerator: EnumTest.Days :: Tue WedÌ4ÎEnumTest.DaysÖ0 enumerator: EnumTest.Days :: Wed geany-2.0/tests/ctags/semicolon.f900000644000175000017500000000013414514252267014160 00000000000000 MODULE SEMI INTEGER (4) :: VAR1; INTEGER (4) VAR2 END MODULE SEMI geany-2.0/tests/ctags/java_enum.java0000644000175000017500000000037214514252267014464 00000000000000public class C { public enum TrivialEnum { FIRST_VALUE, SECOND_VALUE } public enum FancyEnum { A(1), B(2); private int i; FancyEnum(int i) { this.i = i; } void m() { } } public enum FancyEnum2 { X, Y; void m2() { } } } geany-2.0/tests/ctags/simple.ts0000644000175000017500000001046514514252267013521 00000000000000class CPoint { x: number; y: number; constructor(x: number, y: number) { this.x = x; this.y = y; } } class BankAccount { balance = 0; deposit(credit: number) { this.balance += credit; return this.balance; } } class CheckingAccount extends BankAccount { constructor(balance: number) { super(balance); } writeCheck(debit: number) { this.balance -= debit; } } class List { next: List = null; constructor(public item: T) { } insertAfter(item: T) { var temp = this.next; this.next = new List(item); this.next.next = temp; } log() { console.log(this.item.name); } // ... } class C { x: number; static x: string; } class Messenger { message = "Hello World"; start() { var _this = this; setTimeout(function() { alert(_this.message); }, 3000); } }; class D { data: string | string[]; getData() { var data = this.data; return typeof data === "string" ? data : data.join(" "); } } class Point { protected fakePointBuilder: () => { x: number, y: number }; constructor(public x: number, public y: number) { } public length() { return Math.sqrt(this.x * this.x + this.y * this.y); } static origin = new Point(0, 0); } class A { private x: number; protected y: number; public fun: (a: 22 | 30, b: CPoint) => number | string; static f(a: A, b: B) { a.x = 1; // Ok b.x = 1; // Ok a.y = 1; // Ok b.y = 1; // Ok } getXAsT(): T { return this.x as T; } register(...args) { return this.f(...args); } longArgsFun(options: { root: string; prefix?: string; setHeaders?: Function; send?: any; }) { return this.f(options); } closure( x: number, ): (path: string, callback: Function) => any { const normalizedPath = path === '/*' ? '' : path; } } namespace Validation { export interface StringValidator { isAcceptable(s: string): boolean; } const lettersRegexp = /^[A-Za-z]+$/; const numberRegexp = /^[0-9]+$/; export class LettersOnlyValidator implements StringValidator { isAcceptable(s: string) { return lettersRegexp.test(s); } } export class ZipCodeValidator implements StringValidator { isAcceptable(s: string) { return s.length === 5 && numberRegexp.test(s); } } } // Some samples to try let strings = ["Hello", "98052", "101"]; // Validators to use let validators: { [s: string]: Validation.StringValidator; } = {}; validators["ZIP code"] = new Validation.ZipCodeValidator(); validators["Letters only"] = new Validation.LettersOnlyValidator(); // Show whether each string passed each validator for (let s of strings) { for (let name in validators) { console.log(`"${ s }" - ${ validators[name].isAcceptable(s) ? "matches" : "does not match" } ${ name }`); } } interface Mover { move(): void getStatus(): { speed: number } } interface Shaker { shake(): void getStatus(): { frequency: number } } interface MoverShaker extends Mover, Shaker { getStatus(/*)*/): { speed: number; frequency: number } //somethingCommentedOut(): string getSomething(): /* } */ void getSomethingSophisticated()/* comment block */: void getTpl(): Promise } interface SimpleRecord { propertyA: number propertyB: string readonly propertyC: [] withoutType? } interface Document { createElement(tagName: "div"): HTMLDivElement createElement(tagName: "span"): HTMLSpanElement createElement(tagName: "canvas"): HTMLCanvasElement createElement(tagName: string): HTMLElement } interface CompilerOptions { strict?: boolean sourcePath?: string targetPath?: string } interface List { data: T next: List owner: List> } interface JQuery { text(content: string) } interface JQueryStatic { get(url: string, callback: (data: string) => any) (query: string): JQuery } interface Array { length: number [x: number]: T // Other members } enum Color { Red, Green, Blue } enum Test { A, B, C = Math.floor(Math.random() * 1000), D = 10, E } export enum Style { None = 0, Bold = 1, Italic = 2, Underline = 4, Emphasis = Bold | Italic, Hyperlink = Bold | Underline } const enum Comparison { LessThan = -1, EqualTo = 0, GreaterThan = 1 } function add(x, y) { return x + y; }geany-2.0/tests/ctags/fortran_line_continuation.f90.tags0000644000175000017500000000012214514252267020376 00000000000000do_stuffÌ16Ö0 function: do_stuff do_stuff_againÌ16Ö0 function: do_stuff_again geany-2.0/tests/ctags/bug961001.v.tags0000644000175000017500000000041014514252267014227 00000000000000GUESTAÌ16384Ö0 variable: GUESTA GUESTBÌ16384Ö0 variable: GUESTB GUESTCÌ16384Ö0 variable: GUESTC GUESTDÌ16384Ö0 variable: GUESTD HOSTAÌ16384Ö0 variable: HOSTA HOSTBÌ16384Ö0 variable: HOSTB HOSTCÌ16384Ö0 variable: HOSTC HOSTDÌ16384Ö0 variable: HOSTD geany-2.0/tests/ctags/bug734933.f90.tags0000644000175000017500000000204214514252267014377 00000000000000ADD_COMPONENTSÌ128ÎMDCOMPONENTSÖ0 method: MDCOMPONENTS :: ADD_COMPONENTS COMPÌ16384ÎMDCOMPONENTSÖ0 variable: MDCOMPONENTS :: COMP COMPONENTÌ1ÎMDCOMPONENTSÖ0 class: MDCOMPONENTS :: COMPONENT COMPONENTSÌ16384ÎMDCOMPONENTSÖ0 variable: MDCOMPONENTS :: COMPONENTS COMPONENTS_TMPÌ16384ÎMDCOMPONENTSÖ0 variable: MDCOMPONENTS :: COMPONENTS_TMP COMPONENT_POINTERÌ1ÎMDCOMPONENTSÖ0 class: MDCOMPONENTS :: COMPONENT_POINTER COMP_TMPÌ16384ÎMDCOMPONENTSÖ0 variable: MDCOMPONENTS :: COMP_TMP LIM_COMPONENTSÌ16384ÎMDCOMPONENTSÖ0 variable: MDCOMPONENTS :: LIM_COMPONENTS MDCOMPONENTSÌ256Ö0 namespace: MDCOMPONENTS MEMDEALLOCÌ32ÎMDCOMPONENTSÖ0 interface: MDCOMPONENTS :: MEMDEALLOC NAMEÌ64ÎCOMPONENTÖ0 member: COMPONENT :: NAME NCOMPÌ16384ÎMDCOMPONENTSÖ0 variable: MDCOMPONENTS :: NCOMP NUM_COMPONENTSÌ16384ÎMDCOMPONENTSÖ0 variable: MDCOMPONENTS :: NUM_COMPONENTS NUM_PARTÌ64ÎCOMPONENTÖ0 member: COMPONENT :: NUM_PART PÌ64ÎCOMPONENT_POINTERÖ0 member: COMPONENT_POINTER :: P PART_LISTÌ64ÎCOMPONENTÖ0 member: COMPONENT :: PART_LIST geany-2.0/tests/ctags/dotted-names.json0000644000175000017500000000066314514252267015136 00000000000000{ "first.name": "John", "last.name": "Smith", "is.alive": true, "age": 25, "height_cm": 167.6, "address": { "street.address": "21 2nd Street", "city": "New York", "state": "NY", "postal.code": "10021-3100" }, "phone.numbers": [ { "type": "home", "number": "212 555-1234" }, { "type": "office", "number": "646 555-4567" } ], "children": [], "spouse": null } geany-2.0/tests/ctags/random.sql.tags0000644000175000017500000000165014514252267014612 00000000000000SeedÌ16384ÎrandomÖ0 variable: random :: Seed get_randÌ256ÎrandomÖ0 namespace: random :: get_rand get_randÌ1024ÎrandomÖ0 prototype: random :: get_rand get_rand_maxÌ256ÎrandomÖ0 namespace: random :: get_rand_max get_rand_maxÌ1024ÎrandomÖ0 prototype: random :: get_rand_max incrementÌ16384ÎrandomÖ0 variable: random :: increment multiplierÌ16384ÎrandomÖ0 variable: random :: multiplier randÌ16ÎrandomÖ0 function: random :: rand randÌ1024ÎrandomÖ0 prototype: random :: rand rand_maxÌ16ÎrandomÖ0 function: random :: rand_max rand_maxÌ1024ÎrandomÖ0 prototype: random :: rand_max rand_stringÌ16ÎrandomÖ0 function: random :: rand_string rand_stringÌ1024ÎrandomÖ0 prototype: random :: rand_string randomÌ512Ö0 package: random smallerÌ16ÎrandomÖ0 function: random :: smaller smallerÌ1024ÎrandomÖ0 prototype: random :: smaller srandÌ256ÎrandomÖ0 namespace: random :: srand srandÌ1024ÎrandomÖ0 prototype: random :: srand geany-2.0/tests/ctags/return-types.go0000644000175000017500000000041714514252267014664 00000000000000package main func foo() *struct {a int; b func()} { return nil } func bar() (a int, b func(a int), c interface{}, d string) { return 0, nil, nil, "" } func baz() *[20*3+1]map[chan<- /* map[int]int */<-chan int]map[interface{}]*string { return nil } func main() { }geany-2.0/tests/ctags/bug842077.pl.tags0000644000175000017500000000003314514252267014411 00000000000000testÌ16Ö0 function: test geany-2.0/tests/ctags/keyword_delegate.cs0000644000175000017500000000216314514252267015521 00000000000000// keyword_delegate.cs // delegate declaration delegate void MyDelegate(int i); class Program { public static void Main() { TakesADelegate(new MyDelegate(DelegateFunction)); } public static void TakesADelegate(MyDelegate SomeFunction) { SomeFunction(21); } public static void DelegateFunction(int i) { System.Console.WriteLine("Called by delegate with number: {0}.", i); } } // // keyword_delegate2.cs // Calling both static and instance methods from delegates using System; // delegate declaration delegate void MyDelegate(); public class MyClass { public void InstanceMethod() { Console.WriteLine("A message from the instance method."); } static public void StaticMethod() { Console.WriteLine("A message from the static method."); } } public class MainClass { static public void Main() { MyClass p = new MyClass(); // Map the delegate to the instance method: MyDelegate d = new MyDelegate(p.InstanceMethod); d(); // Map to the static method: d = new MyDelegate(MyClass.StaticMethod); d(); } } geany-2.0/tests/ctags/backslashes.c.tags0000644000175000017500000000123514514252267015237 00000000000000MACRO1Ì65536Ö0 macro: MACRO1 MACRO2Ì131072Í(x)Ö0 macro_arg: MACRO2(x) MACRO3Ì131072Í(y)Ö0 macro_arg: MACRO3(y) TÌ4096Ö0Ïint typedef: int T func1Ì1024Í(int var1,int var2,...)Ö0Ïint prototype: int func1(int var1,int var2,...) func2Ì1024Í(int var1,int var2,...)Ö0Ïint prototype: int func2(int var1,int var2,...) func3Ì1024Í(T var1,T var2,...)Ö0Ïint prototype: int func3(T var1,T var2,...) func4Ì1024Í(T var1,T var2,...)Ö0Ïint prototype: int func4(T var1,T var2,...) func5Ì1024Í(int var1,int var2,...)Ö0Ïint prototype: int func5(int var1,int var2,...) func6Ì1024Í(void)Ö0Ïint prototype: int func6(void) func7Ì1024Í(int a)Ö0Ïint prototype: int func7(int a) geany-2.0/tests/ctags/readlong.sql0000644000175000017500000000272014514252267014167 00000000000000rem ----------------------------------------------------------------------- rem URL: http://www.orafaq.com/scripts/plsql/readlong.txt rem Filename: readlong.sql rem Purpose: Fetch Long column values piece-wise from PL/SQL rem Date: 12-Jan-1999 rem Author: Frank Naude (frank@ibi.co.za) rem ----------------------------------------------------------------------- set serveroutput on -- Create test table drop table longtable; create table longtable (longcol long) tablespace TOOLS; insert into longtable values ( rpad('x', 257, 'QWERTY') ); DECLARE cur1 PLS_INTEGER := DBMS_SQL.OPEN_CURSOR;; rc NUMBER; long_piece VARCHAR2(256); piece_len INTEGER := 0; long_tab DBMS_SQL.VARCHAR2S; long_len INTEGER := 0; BEGIN DBMS_SQL.PARSE(cur1, 'select longcol from longtable', DBMS_SQL.NATIVE); DBMS_SQL.DEFINE_COLUMN_LONG(cur1, 1); rc := DBMS_SQL.EXECUTE(cur1); rc := DBMS_SQL.FETCH_ROWS(cur1); -- Get one row -- Loop until all pieces of the long column are processed LOOP DBMS_SQL.COLUMN_VALUE_LONG(cur1, 1, 256, long_len, long_piece, piece_len); EXIT WHEN piece_len = 0; DBMS_OUTPUT.PUT_LINE('Long piece len='|| piece_len); long_tab( NVL(long_tab.LAST, 0)+1 ) := long_piece; -- Add piece to table long_len := long_len + piece_len; END LOOP; DBMS_SQL.CLOSE_CURSOR(cur1); DBMS_OUTPUT.PUT_LINE('Total long col fetched, len='|| long_len); END; / geany-2.0/tests/ctags/macros.c0000644000175000017500000000031214514252267013276 00000000000000#define VARIABLE_LIKE some_value #define FUNCTION_LIKE(a,b) (a + b) #pragma weak WeakSymbol = StrongSymbol /* handling of spoofing macros */ MACRO(foo); void prototype __ARGS((int arg1, void *arg2)); geany-2.0/tests/ctags/interface_indexers.cs0000644000175000017500000000170514514252267016045 00000000000000// cs_interface_indexers.cs using System; // Indexer on an interface: public interface IMyInterface { // indexer declaration: int this[int index] { get; set; } } // Implementing the interface: class IndexerClass : IMyInterface { private int [] myArray = new int[100]; public int this [int index] // indexer declaration { get { // Check the index limits if (index < 0 || index >= 100) return 0; else return myArray[index]; } set { if (!(index < 0 || index >= 100)) myArray[index] = value; } } } public class MainClass { public static void Main() { IndexerClass b = new IndexerClass(); // call the indexer to initialize the elements #3 and #5: b[2] = 4; b[5] = 32; for (int i=0; i<=10; i++) { Console.WriteLine("Element #{0} = {1}", i, b[i]); } } } geany-2.0/tests/ctags/objectivec_interface.mm0000644000175000017500000000245314514252267016346 00000000000000// // commentary test // SupaView // // Created by Vincent Berthoux on 14/06/10. // Copyright 2010 __MyCompanyName__. All rights reserved. // #import #import "LayoutTree.h" @class LayoutTree; @class FolderTree; #define A_MACRO_TEST typedef something SampleTypedefObjC; // Mer & no_struct_name must not be present in output // tag # define ANOTHER_MACRO( WITH, MOAR ) \ Mer( ) \ struct no_struct_name struct aStruct { int aStructMember; char *anotherStructMember[ NOT_IN_TAG ]; }; #pragma DONTCARE /* :-) */ @interface FileTree : NSObject { NSString *name; LayoutTree *representation; FolderTree *parent[THISISNOTATAG]; FileSize diskSize; } - (id)initWithName:(NSString*)treeName andSize:(uint64_t)size atPlace:(FolderTree*)parentFolder; - (id)initWithName:(NSString*)treeName atPlace:(FolderTree*)parentFolder; - (void)dealloc; - (FileSize)getDiskSize; - (LayoutTree*)createLayoutTree; @end @interface FolderTree : FileTree { NSMutableArray *children; } - (id)initWithName:(NSString*)treeName atPlace:(FolderTree*)parentFolder; - (void)dealloc; - (FolderTree*)addChild:(FileTree*)subTree; - (void) populateChildList:(NSString*)root; - (LayoutTree*)createLayoutTree; @end geany-2.0/tests/ctags/ada-expression-function-generic.adb.tags0000644000175000017500000000063414514252267021441 00000000000000Digit_To_CharacterÌ16ÎGeneric_Integer_ImagesÖ0 function: Generic_Integer_Images :: Digit_To_Character Digit_To_CharacterÌ1024ÎGeneric_Integer_ImagesÖ0 prototype: Generic_Integer_Images :: Digit_To_Character Generic_Integer_ImagesÌ512ÎMy_PackageÖ0 package: My_Package :: Generic_Integer_Images My_PackageÌ16Ö0 function: My_Package Signed_AddressÌ4096ÎMy_PackageÖ0 typedef: My_Package :: Signed_Address geany-2.0/tests/ctags/keyword_namespace.cs.tags0000644000175000017500000000131414514252267016635 00000000000000AlternativeNestedNameSpaceClassÌ1ÎSomeNameSpace.NestedÖ0 class: SomeNameSpace.Nested :: AlternativeNestedNameSpaceClass MainÌ128Í()ÎSomeNameSpace.MyClassÖ0Ïpublic void method: public void SomeNameSpace.MyClass :: Main() MyClassÌ1ÎSomeNameSpaceÖ0 class: SomeNameSpace :: MyClass NestedÌ256ÎSomeNameSpaceÖ0 namespace: SomeNameSpace :: Nested NestedNameSpaceClassÌ1ÎSomeNameSpace.NestedÖ0 class: SomeNameSpace.Nested :: NestedNameSpaceClass SayHelloÌ128Í()ÎSomeNameSpace.Nested.NestedNameSpaceClassÖ0Ïpublic void method: public void SomeNameSpace.Nested.NestedNameSpaceClass :: SayHello() SomeNameSpaceÌ256Ö0 namespace: SomeNameSpace SomeNameSpace.NestedÌ256Ö0 namespace: SomeNameSpace.Nested geany-2.0/tests/ctags/bug1548443.cpp0000644000175000017500000000010714514252267013706 00000000000000union TestUnion { int _number; }; struct TestStruct { int _number; }; geany-2.0/tests/ctags/bug556646.c.tags0000644000175000017500000000235714514252267014237 00000000000000AÌ4Îtask_indx_typeÖ0 enumerator: task_indx_type :: A INDX_C1Ì4Îtask_indx_typeÖ0 enumerator: task_indx_type :: INDX_C1 INDX_C2Ì4Îtask_indx_typeÖ0 enumerator: task_indx_type :: INDX_C2 INDX_IM1Ì4Îtask_indx_typeÖ0 enumerator: task_indx_type :: INDX_IM1 INDX_IM2Ì4Îtask_indx_typeÖ0 enumerator: task_indx_type :: INDX_IM2 INDX_LÌ4Îtask_indx_typeÖ0 enumerator: task_indx_type :: INDX_L INDX_L2Ì4Îtask_indx_typeÖ0 enumerator: task_indx_type :: INDX_L2 INDX_MÌ4Îtask_indx_typeÖ0 enumerator: task_indx_type :: INDX_M INDX_NILÌ4Îtask_indx_typeÖ0 enumerator: task_indx_type :: INDX_NIL INDX_PÌ4Îtask_indx_typeÖ0 enumerator: task_indx_type :: INDX_P INDX_RÌ4Îtask_indx_typeÖ0 enumerator: task_indx_type :: INDX_R INDX_R2Ì4Îtask_indx_typeÖ0 enumerator: task_indx_type :: INDX_R2 INDX_SÌ4Îtask_indx_typeÖ0 enumerator: task_indx_type :: INDX_S INDX_S1Ì4Îtask_indx_typeÖ0 enumerator: task_indx_type :: INDX_S1 INDX_S2Ì4Îtask_indx_typeÖ0 enumerator: task_indx_type :: INDX_S2 INDX_S3Ì4Îtask_indx_typeÖ0 enumerator: task_indx_type :: INDX_S3 INDX_S4Ì4Îtask_indx_typeÖ0 enumerator: task_indx_type :: INDX_S4 INDX_TÌ4Îtask_indx_typeÖ0 enumerator: task_indx_type :: INDX_T INDX_T2Ì4Îtask_indx_typeÖ0 enumerator: task_indx_type :: INDX_T2 task_indx_typeÌ2Ö0 enum: task_indx_type geany-2.0/tests/ctags/js-let.js0000644000175000017500000000012414514252267013403 00000000000000let a = 1; let b = 0; let group = { x:1, y:1, z:1, }; let func = function(){} geany-2.0/tests/ctags/simple.php.tags0000644000175000017500000000076714514252267014623 000000000000004siteÌ16384Ö0 variable: 4site CONSTANTÌ65536Ö0 macro: CONSTANT CartÌ1Ö0 class: Cart VarÌ16384Ö0 variable: Var _4siteÌ16384Ö0 variable: _4site add_itemÌ16Í($artnr, $num)ÎCartÖ0 function: Cart :: add_item($artnr, $num) fooÌ16Í($arg_1, $arg_2, ..., $arg_n)Ö0 function: foo($arg_1, $arg_2, ..., $arg_n) itemsÌ16384ÎCartÖ0 variable: Cart :: items remove_itemÌ16Í($artnr, $num)ÎCartÖ0 function: Cart :: remove_item($artnr, $num) täyteÌ16384Ö0 variable: t varÌ16384Ö0 variable: var geany-2.0/tests/ctags/js-class-related-unterminated.js.tags0000644000175000017500000000117714514252267021005 00000000000000AÌ64ÎClsÖ0 member: Cls :: A BÌ1Í(a, b)ÎClsÖ0 class: Cls :: B(a, b) CÌ1Í()ÎClsÖ0 class: Cls :: C() ClsÌ1Ö0 class: Cls SubÌ1Ö0 class: Sub SubÌ1Í()ÎCls.BÖ0 class: Cls.B :: Sub() dyn1Ì128ÎSubÖ0 method: Sub :: dyn1 m1Ì128Í(a)ÎCls.BÖ0 method: Cls.B :: m1(a) m2Ì128Í(b)ÎCls.BÖ0 method: Cls.B :: m2(b) m3Ì128Í(c)ÎCls.BÖ0 method: Cls.B :: m3(c) m4Ì128Í(d)ÎCls.BÖ0 method: Cls.B :: m4(d) m5Ì128Í(e)ÎCls.BÖ0 method: Cls.B :: m5(e) m6Ì128Í(f)ÎCls.BÖ0 method: Cls.B :: m6(f) mainÌ16Í()Ö0 function: main() n1Ì128Í()ÎCls.CÖ0 method: Cls.C :: n1() n2Ì128Í()ÎCls.CÖ0 method: Cls.C :: n2() geany-2.0/tests/ctags/internal.cs0000644000175000017500000000015614514252267014017 00000000000000// Assembly1.cs // compile with: /target:library internal class BaseClass { public static int IntM = 0; } geany-2.0/tests/ctags/bug2777310.js.tags0000644000175000017500000000017014514252267014473 00000000000000aÌ16384Ö0 variable: a bÌ16384Ö0 variable: b xÌ16384Ö0 variable: x yÌ16384Ö0 variable: y zÌ16384Ö0 variable: z geany-2.0/tests/ctags/objectivec_protocol.mm0000644000175000017500000000006714514252267016246 00000000000000 @protocol Locking - (void)lock; - (void)unlock; @end geany-2.0/tests/ctags/recursive.f95.tags0000644000175000017500000000063614514252267015150 00000000000000anon_interface_1Ì32ÎapproxÖ1 interface: approx :: anon_interface_1 flags: 1 anon_interface_2Ì32Îapprox2Ö1 interface: approx2 :: anon_interface_2 flags: 1 approxÌ256Ö0 namespace: approx approx2Ì256Ö0 namespace: approx2 partsÌ16384ÎapproxÖ0 variable: approx :: parts parts2Ì16384Îapprox2Ö0 variable: approx2 :: parts2 yÌ16384ÎapproxÖ0 variable: approx :: y zÌ16384Îapprox2Ö0 variable: approx2 :: z geany-2.0/tests/ctags/preprocessor.f90.tags0000644000175000017500000000027414514252267015660 00000000000000InvisibleÌ256Ö0 namespace: Invisible MainÌ2048Ö0 struct: Main SpillsOutsideÌ16ÎInvisibleÖ0 function: Invisible :: SpillsOutside nopeÌ16384ÎInvisibleÖ0 variable: Invisible :: nope geany-2.0/tests/ctags/js-scope.js0000644000175000017500000000037214514252267013735 00000000000000 function A() { this.a = 1; } A.prototype = { m1 : function() { this.a = 2; foo.bar.baz.hello(1); foo.bar.baz.hello(2); foo.bar.baz.hello(3); }, m2: function() { return this.a; }, }; geany-2.0/tests/ctags/cpp_destructor.cpp0000644000175000017500000000007214514252267015415 00000000000000A::~A() { } B:: ~B () { } // bug 1585745 C:: ~ C () { } geany-2.0/tests/ctags/enum.java0000644000175000017500000000064514514252267013466 00000000000000public enum e { A, // should be 'e', not 'f' B(), // should be 'e', not 'm' C(1), // should be 'e', not missing D, // should be 'e', not 'f' E(), // should be 'e', not 'm' F(1), // should be 'e', not missing ; public String string; public final Shape shape; public final boolean twoKeywordsInARow; public String getString() { return string; } public final Shape getShape() { return shape; } } geany-2.0/tests/ctags/recursive.f950000644000175000017500000000303514514252267014207 00000000000000! result/recursive broken MODULE approx interface recursive function arcsin (angle, terms) ! no result keyword double precision arcsin1 double precision angle integer terms end function arcsin recursive function arcsin1 (angle, terms) result (value) ! no explicit type double precision angle integer terms double precision value end function arcsin1 double precision recursive function arcsin2 (angle, terms) result (value) ! type + recurs double precision angle integer terms end function arcsin2 ! only this function seems to be found recursive double precision function arcsin3 (angle, terms) result (value ) ! recurs + type double precision angle integer terms end function arcsin3 end interface double precision :: y integer :: parts END MODULE MODULE approx2 interface double precision recursive function as (angle, terms) result (value) ! type + recurs double precision angle integer terms end function as recursive double precision function as1 (angle, terms) result (value ) ! recurs + type double precision angle integer terms end function as1 ! but now I can see this one recursive function as2 (angle, terms) ! no result keyword double precision arcsin1 double precision angle integer terms end function as2 ! .. and this one! recursive function as3 (angle, terms) result (value) ! no explicit type double precision angle integer terms double precision value end function as3 end interface double precision :: z integer :: parts2 END MODULE geany-2.0/tests/ctags/bug2411878.cs0000644000175000017500000000006314514252267013534 00000000000000public class C { private System.String m_name; } geany-2.0/tests/ctags/labels.sql0000644000175000017500000000015414514252267013635 00000000000000PROCEDURE outer_procedure IS BEGIN <> DECLARE x INTEGER; BEGIN END my_label; END geany-2.0/tests/ctags/ui5.controller.js0000644000175000017500000000133014514252267015071 00000000000000sap.ui.controller("app.my_form", { successfulRequest: function(data) { switch( data.mParameters.headers.SAAP_SERVICE ) { case SAAP_SERVICE.APPROVAL_DETAIL: if (thisForm.getController().mApproval) { } } }, onInit : function () { this.selectListView = null; sap.ui.getCore().byId("id_createButton").setEnabled(true); }, refreshForm : function (AUFNR) { if (AUFNR && AUFNR !== '') { this.objId = this.oView.sId; } return; }, refreshSettlements : function (AUFNR) { }, setRefreshed : function (value) { this.refreshed = value; }, }); geany-2.0/tests/ctags/bug960316.v.tags0000644000175000017500000000040414514252267014242 00000000000000fail_define_2Ì16384Ö0 variable: fail_define_2 fail_func_2Ì16Ö0 function: fail_func_2 fail_task_2Ì16Ö0 function: fail_task_2 pass_define_1Ì16384Ö0 variable: pass_define_1 pass_func_1Ì16Ö0 function: pass_func_1 pass_task_1Ì16Ö0 function: pass_task_1 geany-2.0/tests/ctags/fortran_line_continuation.f900000644000175000017500000000072514514252267017452 00000000000000! this is a comment and continuation must not be handled in it & ! this is another line of comment #if dummy function & ! just a test for support of comments after a line continuation ! below is a preprocessor line, also just to test continuation #endif ! still testing & do_stuff(a) end function do_stuff function & ! actually the ampersand isn't required at the start of the continuation line #pragma stuff do_stuff_again(b) end function do_stuff_again geany-2.0/tests/ctags/forall_module.f90.tags0000644000175000017500000000034514514252267015755 00000000000000aÌ16384Îwith_forallÖ0 variable: with_forall :: a sub_with_forallÌ128Í(x)Îwith_forallÖ0 method: with_forall :: sub_with_forall(x) twoÌ16Îwith_forallÖ0 function: with_forall :: two with_forallÌ256Ö0 namespace: with_forall geany-2.0/tests/ctags/keyword_static.cs0000644000175000017500000000215714514252267015241 00000000000000// cs_static_keyword.cs // Static members using System; public class Employee { public string id; public string name; public Employee () { } public Employee (string name, string id) { this.name = name; this.id = id; } public static int employeeCounter; public static int AddEmployee() { return ++employeeCounter; } } class MainClass: Employee { public static void Main() { Console.Write("Enter the employee's name: "); string name = Console.ReadLine(); Console.Write("Enter the employee's ID: "); string id = Console.ReadLine(); // Create the employee object: Employee e = new Employee (name, id); Console.Write("Enter the current number of employees: "); string n = Console.ReadLine(); Employee.employeeCounter = Int32.Parse(n); Employee.AddEmployee(); // Display the new information: Console.WriteLine("Name: {0}", e.name); Console.WriteLine("ID: {0}", e.id); Console.WriteLine("New Number of Employees: {0}", Employee.employeeCounter); } } geany-2.0/tests/ctags/make-variable-on-cmdline.mak0000644000175000017500000000002714514252267017066 00000000000000fixme: cmd -g FOO=BAR geany-2.0/tests/ctags/ruby-namespaced-class.rb0000644000175000017500000000010014514252267016350 00000000000000module A module B end end class A::B::C; end puts A::B::C geany-2.0/tests/ctags/square_parens.f90.tags0000644000175000017500000000153014514252267015776 00000000000000SymmetryÌ1ÎsquaretestÖ0 class: squaretest :: Symmetry assigneeÌ16384ÎsquaretestÖ0 variable: squaretest :: assignee executeÌ128Í(state)ÎsquaretestÖ0 method: squaretest :: execute(state) invisibleÌ16384ÎsquaretestÖ0 variable: squaretest :: invisible invisible_fourÌ16384ÎsquaretestÖ0 variable: squaretest :: invisible_four invisible_threeÌ16384ÎsquaretestÖ0 variable: squaretest :: invisible_three invisible_twoÌ16384ÎsquaretestÖ0 variable: squaretest :: invisible_two iterationsÌ64ÎSymmetryÖ0 member: Symmetry :: iterations mainÌ2048Ö0 struct: main matrixÌ64ÎSymmetryÖ0 member: Symmetry :: matrix squaretestÌ256Ö0 namespace: squaretest stateÌ16384ÎsquaretestÖ0 variable: squaretest :: state state_twoÌ16384ÎsquaretestÖ0 variable: squaretest :: state_two symmetriesÌ16384ÎsquaretestÖ0 variable: squaretest :: symmetries geany-2.0/tests/ctags/cxx11-override.cpp0000644000175000017500000000033014514252267015133 00000000000000class Base { public: virtual void foo() = 0; }; class Derived : public Base { virtual void foo() override; virtual void override(); }; void Base::foo() { } void Derived::foo() { } void Derived::override() { } geany-2.0/tests/ctags/cxx11enum.cpp0000644000175000017500000000024514514252267014210 00000000000000 enum A:int {A_a, A_b, A_c}; enum B:long {B_a, B_b, B_c}; enum C:unsigned int {C_a, C_b, C_c}; class Foo { enum D:int {a, b, c}; virtual void foo(enum D a); }; geany-2.0/tests/ctags/block.f90.tags0000644000175000017500000000037214514252267014223 00000000000000BlocksÌ256Ö0 namespace: Blocks MainÌ2048Ö0 struct: Main MyFuncÌ16ÎBlocksÖ0 function: Blocks :: MyFunc iÌ16384ÎBlocksÖ0 variable: Blocks :: i moreintÌ16384ÎMainÖ0 variable: Main :: moreint otherintÌ16384ÎMainÖ0 variable: Main :: otherint geany-2.0/tests/ctags/bug1093123.cpp.tags0000644000175000017500000000005014514252267014626 00000000000000mainÌ16Í()Ö0Ïint function: int main() geany-2.0/tests/ctags/js-implicit-semicolons.js.tags0000644000175000017500000000053514514252267017545 00000000000000aÌ16384Ö0 variable: a bÌ16Í()Ö0 function: b() cÌ16Í()Ö0 function: c() dÌ16384Ö0 variable: d eÌ16Í()Ö0 function: e() fÌ16384Ö0 variable: f gÌ16Í()Ö0 function: g() hÌ16384Ö0 variable: h iÌ16Í()Ö0 function: i() jÌ16Í()Ö0 function: j() kÌ16Ö0 function: k lÌ16Í()Ö0 function: l() mÌ16384Ö0 variable: m nÌ16Í()Ö0 function: n() geany-2.0/tests/ctags/js-class-related-unterminated.js0000644000175000017500000000217014514252267020042 00000000000000 var Cls = { // add a member just so Cls is recognized as a class from the start A: {} } Cls.B = function(a, b) { this.a = a; this.b = b; } Cls.B.Sub = function() { this.a = 0 } Cls.B.prototype.m1 = function(a) { this.a = a; if (a > 2) { this.a *= 2 } } Cls.B.prototype.m2 = function(b) { var a = b } Cls.B.prototype.m3 = function(c) { this.c = c } Cls.B.prototype.m4 = function(d) { this.d = d } Cls.B.prototype.m5 = function(e) { /* this should rather be written `Cls.B.Sub.prototype.dyn1 = this.m6`, but * then parser then thinks it's a child of this very scope. it isn't really * possible to fix this as the only reason it's actually not a child of the * current scope is because it exists in the root scope but not in this one */ var Sub = Cls.B.Sub; Sub.prototype.dyn1 = this.m4 } Cls.B.prototype.m6 = function(f) { } Cls.C = function () { this.a = 0; } Cls.C.prototype = { n1: function() { Cls.C.prototype = Cls.C.prototype }, n2: function() { } } function main() { var c = new Cls.B(1, 2); var d = new Cls.B.Sub(); print(d.dyn1); c.m5(); print(d.dyn1); } main(); geany-2.0/tests/ctags/bug852368.cpp0000644000175000017500000000137714514252267013643 00000000000000/* Bugs item #852368, was opened at 2003-12-01 23:20 Message generated for change (Tracker Item Submitted) made by Item Submitter You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=106556&aid=852368&group_id=6556 Category: None Group: None Status: Open Resolution: None Priority: 5 Submitted By: Welti Marco (cider101) Assigned to: Nobody/Anonymous (nobody) Summary: c/c++ unabalanced template brackets in signature Initial Comment: hi, ctags 5.5x generates unbalanced template brackets in the method/function signature if a function parameter is a template. i.e. */ void foo(std::vector &); /* generates the following signature signature:void (std::vector<&) let me know if you need more details. regards cider */ geany-2.0/tests/ctags/bug1799343-2.cpp.tags0000644000175000017500000000074014514252267015014 00000000000000AÌ256Ö0 namespace: A BÌ256Ö0 namespace: B CÌ256ÎAÖ0 namespace: A :: C PÌ1Ö0 class: P PÌ1ÎAÖ0 class: A :: P QÌ1ÎAÖ0 class: A :: Q RÌ1ÎA::CÖ0 class: A::C :: R SÌ1ÎBÖ0 class: B :: S fÌ16Í(int v)ÎA::C::RÖ0Ïint function: int A::C::R :: f(int v) tÌ64ÎB::SÖ0Ïint member: int B::S :: t xÌ64ÎA::PÖ0Ïint member: int A::P :: x xÌ64ÎPÖ0Ïint member: int P :: x yÌ64ÎA::QÖ0Ïint member: int A::Q :: y zÌ64ÎA::C::RÖ0Ïint member: int A::C::R :: z geany-2.0/tests/ctags/bug1924919.cpp.tags0000644000175000017500000000027414514252267014656 00000000000000MajorVersionÌ16384ÎmudÖ0Ïstd::string variable: std::string mud :: MajorVersion MinorVersionÌ16384ÎmudÖ0Ïstd::string variable: std::string mud :: MinorVersion mudÌ256Ö0 namespace: mud geany-2.0/tests/ctags/2023624.js.tags0000644000175000017500000000007014514252267013764 00000000000000f1Ì16Í()Ö0 function: f1() f2Ì16Í()Ö0 function: f2() geany-2.0/tests/ctags/cxx11-override.cpp.tags0000644000175000017500000000065214514252267016077 00000000000000BaseÌ1Ö0 class: Base DerivedÌ1Ö0 class: Derived fooÌ16Í()ÎBaseÖ0Ïvoid function: void Base :: foo() fooÌ16Í()ÎDerivedÖ0Ïvoid function: void Derived :: foo() fooÌ1024Í()ÎBaseÖ0Ïvoid prototype: void Base :: foo() fooÌ1024Í()ÎDerivedÖ0Ïvoid prototype: void Derived :: foo() overrideÌ16Í()ÎDerivedÖ0Ïvoid function: void Derived :: override() overrideÌ1024Í()ÎDerivedÖ0Ïvoid prototype: void Derived :: override() geany-2.0/tests/ctags/js-broken-strings.js.tags0000644000175000017500000000015014514252267016522 00000000000000s1Ì16384Ö0 variable: s1 s2Ì16384Ö0 variable: s2 s3Ì16384Ö0 variable: s3 s4Ì16384Ö0 variable: s4 geany-2.0/tests/ctags/make-multi-target.mak.tags0000644000175000017500000000014414514252267016631 00000000000000allÌ16Ö0 function: all barÌ16Ö0 function: bar bazÌ16Ö0 function: baz fooÌ16Ö0 function: foo geany-2.0/tests/ctags/bug1830344.cs0000644000175000017500000000025114514252267013523 00000000000000public class C { public void m() { bool flagCheck = true; if (flagCheck == true) { Console.WriteLine("true"); } else { Console.WriteLine("false"); } } } geany-2.0/tests/ctags/bug1563476.cpp0000644000175000017500000000047014514252267013714 00000000000000int g() { } template< typename Accessor, typename bEnable = void > struct IntroduceBitDef; template< typename Accessor > struct IntroduceBitDef< Accessor, typename boost::enable_if_c< CoreConfig::VERSION <= 3 >::type > { // class body here // anything after this point is not parsed by ctags int f() { } }; geany-2.0/tests/ctags/jsFunc_tutorial.js.tags0000644000175000017500000000627214514252267016327 00000000000000Ball1Ì16Í()Ö0 function: Ball1() Ball3Ì16Í()Ö0 function: Ball3() D1Ì16Í(a, b)Ö0 function: D1(a, b) D2Ì16Í(a, b)Ö0 function: D2(a, b) D2AÌ16Í(a, b)Ö0 function: D2A(a, b) D3Ì16Ö0 function: D3 D4Ì16Ö0 function: D4 D5Ì16Í(myOperator)Ö0 function: D5(myOperator) DT1Ì16Í()Ö0 function: DT1() DT2Ì16Í(message)Ö0 function: DT2(message) DT2AÌ16Í(message)Ö0 function: DT2A(message) DT3Ì16Í()Ö0 function: DT3() DT4Ì1Í(message, specifiedName)Ö0 class: DT4(message, specifiedName) DT5Ì1Í(color, specifiedName, owner, weight)Ö0 class: DT5(color, specifiedName, owner, weight) DT6Ì1Í(name, salary, mySupervisor)Ö0 class: DT6(name, salary, mySupervisor) DT7Ì1Í(name, salary)Ö0 class: DT7(name, salary) DT7AÌ1Í(name, salary)Ö0 class: DT7A(name, salary) DT8Ì1Í(name, salary)Ö0 class: DT8(name, salary) DT9Ì1Í(name, salary)Ö0 class: DT9(name, salary) PT1Ì16Í()Ö0 function: PT1() PT2Ì1Í(name, color)Ö0 class: PT2(name, color) PT3Ì1Í(name, salary)Ö0 class: PT3(name, salary) addÌ16Í(a,b)ÎmyObjectÖ0 function: myObject :: add(a,b) addSalaryÌ128Í(addition)ÎPT3Ö0 method: PT3 :: addSalary(addition) addSalaryFunctionÌ1Í(addition)Ö0 class: addSalaryFunction(addition) addSalaryFunctionDT9Ì1Í(addition)Ö0 class: addSalaryFunctionDT9(addition) ball0Ì16384Ö0 variable: ball0 ball1Ì16384Ö0 variable: ball1 ball2Ì1Ö0 class: ball2 ball3Ì16384Ö0 variable: ball3 ball4Ì16384Ö0 variable: ball4 ball5Ì16384Ö0 variable: ball5 ball6Ì16384Ö0 variable: ball6 ball7Ì16384Ö0 variable: ball7 ball8Ì16384Ö0 variable: ball8 ball9Ì16384Ö0 variable: ball9 balloonÌ16384Ö0 variable: balloon bossÌ16384Ö0 variable: boss boss1Ì16384Ö0 variable: boss1 boss2Ì16384Ö0 variable: boss2 boss3Ì16384Ö0 variable: boss3 calculateÌ16Í(number)ÎgetHalfOf7Ö0 function: getHalfOf7 :: calculate(number) calculateÌ16Í(number)ÎgetHalfOf8Ö0 function: getHalfOf8 :: calculate(number) calculate8Ì16Í(number)Ö0 function: calculate8(number) getHalfOf7Ì16Í(num1, num2, num3)Ö0 function: getHalfOf7(num1, num2, num3) getHalfOf8Ì16Í(num1, num2, num3)Ö0 function: getHalfOf8(num1, num2, num3) getSalaryÌ128Í()ÎDT7Ö0 method: DT7 :: getSalary() getSalaryÌ128Í()ÎDT7AÖ0 method: DT7A :: getSalary() getSalaryÌ128Í()ÎDT8Ö0 method: DT8 :: getSalary() getSalaryÌ128Í()ÎPT3Ö0 method: PT3 :: getSalary() getSalaryFunctionDT9Ì16Í()Ö0 function: getSalaryFunctionDT9() livesInÌ128ÎPT2Ö0 method: PT2 :: livesIn managerÌ16384Ö0 variable: manager myFunction4Ì16Í(message)Ö0 function: myFunction4(message) myFunction5Ì16Í()Ö0 function: myFunction5() myFunction6Ì16Í()Ö0 function: myFunction6() myFunction6AÌ16Í()Ö0 function: myFunction6A() myFunction6AEÌ16Í()Ö0 function: myFunction6AE() myFunction6BÌ16Í()Ö0 function: myFunction6B() myFunction6EÌ16Í()Ö0 function: myFunction6E() myObjectÌ1Ö0 class: myObject my_global_var1Ì16384Ö0 variable: my_global_var1 object1Ì1Ö0 class: object1 object2Ì1Ö0 class: object2 object3Ì1Ö0 class: object3 priceÌ128ÎPT2Ö0 method: PT2 :: price savedFunc6BÌ16Í()Ö0 function: savedFunc6B() sayName4AÌ16Í(name)Ö0 function: sayName4A(name) teamLeaderÌ16384Ö0 variable: teamLeader theAddÌ16Í(a, b)Ö0 function: theAdd(a, b) geany-2.0/tests/ctags/general.cs.tags0000644000175000017500000000150014514252267014547 00000000000000C1Ì1ÎN1Ö0 class: N1 :: C1 C2Ì1ÎN1.C1Ö0 class: N1.C1 :: C2 C2Ì1ÎN1.N2Ö0 class: N1.N2 :: C2 IMyInterfaceÌ32ÎMyNamespace1Ö0 interface: MyNamespace1 :: IMyInterface MainÌ128Í(string[] args)ÎMyNamespace1.MyClass2Ö0Ïpublic void method: public void MyNamespace1.MyClass2 :: Main(string[] args) MyClass1Ì1ÎMyNamespace1Ö0 class: MyNamespace1 :: MyClass1 MyClass2Ì1ÎMyNamespace1Ö0 class: MyNamespace1 :: MyClass2 MyDelegateÌ128Í()ÎMyNamespace1Ö0Ïdelegate int method: delegate int MyNamespace1 :: MyDelegate() MyEnumÌ2ÎMyNamespace1Ö0 enum: MyNamespace1 :: MyEnum MyNamespace1Ì256Ö0 namespace: MyNamespace1 MyNamespace2Ì256ÎMyNamespace1Ö0 namespace: MyNamespace1 :: MyNamespace2 MyStructÌ2048ÎMyNamespace1Ö0 struct: MyNamespace1 :: MyStruct N1Ì256Ö0 namespace: N1 N2Ì256ÎN1Ö0 namespace: N1 :: N2 geany-2.0/tests/ctags/bug1799340.cpp.tags0000644000175000017500000000030014514252267014642 00000000000000f1Ì16Í()Ö0Ïstd::string & function: std::string & f1() f2Ì16Í()Ö0Ïconst std::string & function: const std::string & f2() f3Ì16Í()Ö0Ïstd::string const & function: std::string const & f3() geany-2.0/tests/ctags/bug1800065.cs.tags0000644000175000017500000000014414514252267014456 00000000000000CÌ1Ö0 class: C titleÌ8ÎCÖ0 field: C :: title windowÌ8ÎCÖ0ÏGtk field: Gtk C :: window geany-2.0/tests/ctags/simple.au30000644000175000017500000000130214514252267013551 00000000000000; Taken from https://www.autoitscript.com/autoit3/docs/intro/lang_functions.htm #include #include #include "WindowsConstants.au3" Global $iMagic = 0x377abcaf271c Local $iNumber = 10 Local $iDoubled = 0 For $i = 1 To 10 $iDoubled = MyDouble($iNumber) MsgBox($MB_OK, "", $iNumber & " doubled is " & $iDoubled) $iNumber = $iDoubled Next Exit #Region All functions Func MyDouble($iValue) $iValue = $iValue * 2 Return $iValue EndFunc ;==>MyDouble func MyDouble0($iValue) $iValue = $iValue * 2 Return $iValue EndFunc ;==>MyDouble FUNC MyDouble1($iValue) $iValue = $iValue * 2 Return $iValue EndFunc #EndRegion All functions geany-2.0/tests/ctags/simple.js0000644000175000017500000000423414514252267013504 00000000000000/* * ctags should return the following for parsing this file using: * ctags -f - simple.js * * functions * extra.validFunctionFour * getHalfOf * getHalfOf.calculate * testlib.core.validFunctionSix * testlib.validFunctionFive * validFunctionOne * validFunctionThree * validFunctionThree.innerThree * validFunctionTwo * classes * Database * ValidClassTwo * testlib.extras.ValidClassOne * methods * Database.executeQueryString * Database.getTodaysDate * ValidClassTwo.validMethodFour * ValidClassTwo.validMethodThree * testlib.extras.ValidClassOne.validMethodOne * testlib.extras.ValidClassOne.validMethodTwo * variables * my_global_var1 * my_global_var2 * my_global_var3 * my_global_var4 */ validFunctionOne = function(a,b) {} function validFunctionTwo(a,b) {} function validFunctionThree(a,b) { var innerThree = function(a,b) {} } var my_global_var1 = 33; function extra.validFunctionFour(a,b) {} //pseudo-module setup testlib = {} testlib.core = {} testlib.extras = {} var my_global_var2 = "Something"; testlib.validFunctionFive = function(a,b) {} var invalidInnerFunction = function(a,b) {} testlib.core.validFunctionSix = function(a,b) {} testlib.extras.ValidClassOne = function(a,b) { this.a = a; } testlib.extras.ValidClassOne.prototype = { 'validMethodOne' : function(a,b) {}, 'validMethodTwo' : function(a,b) {} } ValidClassTwo = function () { this.validMethodThree = function() {} // unnamed method this.validMethodFour = function() {} } var my_global_var4 = document.getElementsByTagName("input"); for (var i = 0; i < my_global_var4.length; i++) { var originalvalue = my_global_var4[i].value; my_global_var4[i].onchange = function () { alert(this.value + " == " + originalvalue); } } function getHalfOf(num1, num2, num3) { function calculate(number) { return number/2; } var result=""; result+=calculate(num1)+" "; result+=calculate(num2)+" "; result+=calculate(num3); } var my_global_var3; Database.prototype.getTodaysDate = Database_getTodaysDate; Database.prototype.executeQueryString = Db_executeQueryString; geany-2.0/tests/ctags/cxx14-combined.cpp0000644000175000017500000000030614514252267015102 00000000000000struct Base { virtual void baz() const throw() = 0; }; struct Foo final : public Base { static constexpr auto bar() noexcept { return 1; } virtual void baz() const throw() final override; }; geany-2.0/tests/ctags/actionscript/0000755000175000017500000000000014514253242014426 500000000000000geany-2.0/tests/ctags/actionscript/const2.as0000644000175000017500000000055614514252267016117 00000000000000// https://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/statements.html#const const MIN_AGE:int = 21; const product_array:Array = new Array("Studio", "Dreamweaver", "Flash", "ColdFusion", "Contribute", "Breeze"); product_array.push("Flex"); // array operations are allowed product_array = ["Other"]; // assignment is an error trace(product_array); geany-2.0/tests/ctags/actionscript/packages.as.tags0000644000175000017500000000027714514252267017422 00000000000000C1Ì1ÎP3Ö0 class: P3 :: C1 P1Ì512Ö0 package: P1 P2Ì512Ö0 package: P2 P3Ì512Ö0 package: P3 f1Ì16ÎP2Ö0 function: P2 :: f1 qualified.test.pkgÌ512Ö0 package: qualified.test.pkg geany-2.0/tests/ctags/actionscript/method-attributes.as0000644000175000017500000000063114514252267020345 00000000000000/* Not sure it's really valid, but the goal is to check not choking on * attributes, so so long as it's valid attributes it's fine */ class C { public function f1():void {} private function f2():void {} protected function f3():void {} internal function f4():void {} public function f5():void {} public override function f6():void {} final function f7():void {} native function f8():void {} } geany-2.0/tests/ctags/actionscript/method-attributes.as.tags0000644000175000017500000000041414514252267021301 00000000000000CÌ1Ö0 class: C f1Ì128ÎCÖ0 method: C :: f1 f2Ì128ÎCÖ0 method: C :: f2 f3Ì128ÎCÖ0 method: C :: f3 f4Ì128ÎCÖ0 method: C :: f4 f5Ì128ÎCÖ0 method: C :: f5 f6Ì128ÎCÖ0 method: C :: f6 f7Ì128ÎCÖ0 method: C :: f7 f8Ì128ÎCÖ0 method: C :: f8 geany-2.0/tests/ctags/actionscript/classes.as0000644000175000017500000000053114514252267016335 00000000000000package { class C1 { public function m1():Boolean { return 0; } } class C2 extends C1 {} class C3 {} interface I1 {} interface I2 {} interface I3 extends I1, I2 {} interface I4 extends I3 {} class C4 implements I1 {} class C5 extends C3 implements I1 {} class C6 extends C3 implements I1, I2 {} dynamic class C7{} } geany-2.0/tests/ctags/actionscript/const2.as.tags0000644000175000017500000000012414514252267017043 00000000000000MIN_AGEÌ65536Ö0 macro: MIN_AGE product_arrayÌ65536Ö0 macro: product_array geany-2.0/tests/ctags/actionscript/as-first-token.as.tags0000644000175000017500000000002714514252267020503 00000000000000f1Ì16Ö0 function: f1 geany-2.0/tests/ctags/actionscript/as-first-token.as0000644000175000017500000000002614514252267017545 00000000000000function f1():void {} geany-2.0/tests/ctags/actionscript/const.as.tags0000644000175000017500000000044614514252267016770 00000000000000AlarmClockÌ1Ö0 class: AlarmClock MODE_AUDIOÌ65536ÎAlarmClockÖ0 macro: AlarmClock :: MODE_AUDIO MODE_BOTHÌ65536ÎAlarmClockÖ0 macro: AlarmClock :: MODE_BOTH MODE_VISUALÌ65536ÎAlarmClockÖ0 macro: AlarmClock :: MODE_VISUAL modeÌ16384ÎAlarmClockÖ0 variable: AlarmClock :: mode geany-2.0/tests/ctags/actionscript/const.as0000644000175000017500000000043014514252267016024 00000000000000// https://www.oreilly.com/library/view/essential-actionscript-30/0596526946/ch04s02.html public class AlarmClock { public static const MODE_VISUAL = 1; public static const MODE_AUDIO = 2; public static const MODE_BOTH = 3; private var mode = AlarmClock.MODE_AUDIO; } geany-2.0/tests/ctags/actionscript/classes.as.tags0000644000175000017500000000042714514252267017276 00000000000000C1Ì1Ö0 class: C1 C2Ì1Ö0 class: C2 C3Ì1Ö0 class: C3 C4Ì1Ö0 class: C4 C5Ì1Ö0 class: C5 C6Ì1Ö0 class: C6 C7Ì1Ö0 class: C7 I1Ì32Ö0 interface: I1 I2Ì32Ö0 interface: I2 I3Ì32Ö0 interface: I3 I4Ì32Ö0 interface: I4 m1Ì128ÎC1Ö0 method: C1 :: m1 geany-2.0/tests/ctags/actionscript/sampler.as.tags0000644000175000017500000000201414514252267017276 00000000000000assertÌ128ÎsampleTypesÖ0 method: sampleTypes :: assert bÌ16384ÎsampleTypesÖ0 variable: sampleTypes :: b cpuSamplesÌ16384ÎsampleTypes.sampleTypesÖ0 variable: sampleTypes.sampleTypes :: cpuSamples delSamplesÌ16384ÎsampleTypes.sampleTypesÖ0 variable: sampleTypes.sampleTypes :: delSamples dosÌ16384ÎsampleTypes.sampleTypesÖ0 variable: sampleTypes.sampleTypes :: dos flash.display.SpriteÌ32768Ö0 externvar: flash.display.Sprite flash.sampler.*Ì32768Ö0 externvar: flash.sampler.* flash.system.*Ì32768Ö0 externvar: flash.system.* flash.utils.*Ì32768Ö0 externvar: flash.utils.* idsÌ16384ÎsampleTypes.sampleTypesÖ0 variable: sampleTypes.sampleTypes :: ids lastTimeÌ16384ÎsampleTypes.sampleTypesÖ0 variable: sampleTypes.sampleTypes :: lastTime newSamplesÌ16384ÎsampleTypes.sampleTypesÖ0 variable: sampleTypes.sampleTypes :: newSamples nosÌ16384ÎsampleTypes.sampleTypesÖ0 variable: sampleTypes.sampleTypes :: nos sampleTypesÌ1Ö0 class: sampleTypes sampleTypesÌ128ÎsampleTypesÖ0 method: sampleTypes :: sampleTypes geany-2.0/tests/ctags/actionscript/sampler.as0000644000175000017500000000415214514252267016346 00000000000000// https://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/sampler/Sample.html package { import flash.sampler.* import flash.system.* import flash.utils.* import flash.display.Sprite public class sampleTypes extends Sprite { var b:Boolean = true public function sampleTypes() { flash.sampler.startSampling(); for(var i:int=0;i<10000;i++) new Object(); var cpuSamples:Array=[]; var newSamples:Array=[]; var delSamples:Array=[]; var ids:Array=[] var lastTime:Number=0; for each(var s:Sample in getSamples()) { assert(s.time > 0); // positive assert(Math.floor(s.time) == s.time, s.time); // integral assert(s.time >= lastTime, s.time + ":" + lastTime); // ascending assert(s.stack == null || s.stack is Array) if(s.stack) { assert(s.stack[0] is StackFrame); assert(s.stack[0].name is String); } if(s is NewObjectSample) { var nos = NewObjectSample(s); assert(s.id > 0, s.id); assert(s.type is Class, getQualifiedClassName(s.type)); newSamples.push(s); ids[s.id] = "got one"; } else if(s is DeleteObjectSample) { var dos = DeleteObjectSample(s); delSamples.push(s); assert(ids[dos.id] == "got one"); } else if(s is Sample) cpuSamples.push(s); else { assert(false); } lastTime = s.time; } trace(b) trace(newSamples.length > 0) trace(cpuSamples.length > 0) trace(delSamples.length > 0) } private function assert(e:Boolean, mess:String=null):void { b = e && b; if(true && !e) { if(mess) trace(mess); trace(new Error().getStackTrace()); } } } } geany-2.0/tests/ctags/actionscript/packages.as0000644000175000017500000000015614514252267016461 00000000000000package P1 {} package P2 { function f1() {} } package P3 { class C1 {} } package qualified.test . pkg { } geany-2.0/tests/ctags/css-trivial.css0000644000175000017500000000016214514252267014623 00000000000000 html{ font: sans-serif; } a{ color: red; } p{ text-align: justify; } input, textarea{ border: 1px solid green; } geany-2.0/tests/ctags/simple.hx0000644000175000017500000000046614514252267013512 00000000000000enum Color { Red; Green; Blue; Rgb(r:Int, g:Int, b:Int); } interface Printable { public function toString():String; } typedef User = { var age : Int; var name : String; } class Main { static var member:String = "bar"; static public function main():Void { trace("Hello World"); } }geany-2.0/tests/ctags/array_ref_and_out.cs.tags0000644000175000017500000000063214514252267016622 00000000000000FillArrayÌ128Í(out int[] myArray)ÎTestOutÖ0Ïpublic void method: public void TestOut :: FillArray(out int[] myArray) MainÌ128Í()ÎTestOutÖ0Ïpublic void method: public void TestOut :: Main() MyMethodÌ128Í(out int[] arr)Ö0Ïpublic void method: public void MyMethod(out int[] arr) MyMethodÌ128Í(ref int[] arr)Ö0Ïpublic void method: public void MyMethod(ref int[] arr) TestOutÌ1Ö0 class: TestOut geany-2.0/tests/ctags/bug556645.c0000644000175000017500000000200714514252267013271 00000000000000/* From noreply@sourceforge.net Wed May 29 23:11:25 2002 Date: Wed, 15 May 2002 23:25:52 -0700 From: noreply@sourceforge.net To: noreply@sourceforge.net Subject: [ ctags-Bugs-556645 ] Some typedef can not be tagged in C code Bugs item #556645, was opened at 2002-05-16 14:25 You can respond by visiting: http://sourceforge.net/tracker/?func=detail&atid=106556&aid=556645&group_id=6556 Category: None Group: None Status: Open Resolution: None Priority: 5 Submitted By: Howard Wu (howardhbwu) Assigned to: Nobody/Anonymous (nobody) Summary: Some typedef can not be tagged in C code Initial Comment: My Ctags version:5.2.3 The typedef of "Qtype" as the following, */ #define A1(_type, _length) \ struct { \ unsigned int head; \ unsigned int tail; \ bool is_full; \ _type queue[_length]; \ } typedef A1(ilm_struct, 1) Qtype; /* As using ctags, the "Qtype" can not be tagged by it. */ geany-2.0/tests/ctags/complex-return.js.tags0000644000175000017500000000173214514252267016134 00000000000000anon_function_1Ì16Í()Îclass2.c2m1Ö1 function: class2.c2m1 :: anon_function_1() flags: 1 anon_function_2Ì16Í(n)Îclass3.c3m1Ö1 function: class3.c3m1 :: anon_function_2(n) flags: 1 c2m1Ì128Í()Îclass2Ö0 method: class2 :: c2m1() c2m2Ì128Í(f)Îclass2Ö0 method: class2 :: c2m2(f) c2m3Ì128Í(f)Îclass2Ö0 method: class2 :: c2m3(f) c3m1Ì128Í()Îclass3Ö0 method: class3 :: c3m1() c3m2Ì128Í()Îclass3Ö0 method: class3 :: c3m2() class1Ì1Í()Ö0 class: class1() class2Ì1Í()Ö0 class: class2() class3Ì1Í()Ö0 class: class3() class4Ì1Í()Ö0 class: class4() func1Ì16Í()Ö0 function: func1() func2Ì16Í()Ö0 function: func2() method1Ì128Í()Îclass1Ö0 method: class1 :: method1() method1Ì128Í()Îclass4Ö0 method: class4 :: method1() method2Ì128Í()Îclass1Ö0 method: class1 :: method2() method2Ì128Í()Îclass4Ö0 method: class4 :: method2() method3Ì128Í()Îclass1Ö0 method: class1 :: method3() method4Ì128Í()Îclass1Ö0 method: class1 :: method4() geany-2.0/tests/ctags/make-variable-on-cmdline.mak.tags0000644000175000017500000000003514514252267020022 00000000000000fixmeÌ16Ö0 function: fixme geany-2.0/tests/ctags/moniker.x68.asm.tags0000644000175000017500000000101214514252267015373 00000000000000CHECK2Ì256Ö0 namespace: CHECK2 DUMMYÌ65536Ö0 macro: DUMMY F_NAMEÌ65536Ö0 macro: F_NAME INITIALÌ256Ö0 namespace: INITIAL PRNSURNAMEÌ256Ö0 namespace: PRNSURNAME PROMPT1Ì65536Ö0 macro: PROMPT1 PROMPT2Ì65536Ö0 macro: PROMPT2 PRTSTRÌ65536Ö0 macro: PRTSTR QUITÌ256Ö0 namespace: QUIT READSTRÌ65536Ö0 macro: READSTR RETURNFALSEÌ256Ö0 namespace: RETURNFALSE RETURNTRUEÌ256Ö0 namespace: RETURNTRUE STARTÌ256Ö0 namespace: START SURNAMEÌ256Ö0 namespace: SURNAME S_NAMEÌ65536Ö0 macro: S_NAME geany-2.0/tests/ctags/keyword_public.cs0000644000175000017500000000052514514252267015225 00000000000000// protected_public.cs // Public access using System; class MyClass1 { public int x; public int y; } class MyClass2 { public static void Main() { MyClass1 mC = new MyClass1(); // Direct access to public members: mC.x = 10; mC.y = 15; Console.WriteLine("x = {0}, y = {1}", mC.x, mC.y); } } geany-2.0/tests/ctags/stdcall.f0000644000175000017500000001263414514252267013455 00000000000000* Obtained from http://www.nag.com/local/nagping/np006a3.asp * D02CJF Example Program Text * Mark 14 Revised. NAG Copyright 1989. * .. Parameters .. CHARACTER RELABS*15 !NEW INTEGER NOUT PARAMETER (NOUT=6) INTEGER N, IW PARAMETER (N=3,IW=21*N+28) * .. Scalars in Common .. DOUBLE PRECISION H, XEND INTEGER K * .. Local Scalars .. DOUBLE PRECISION PI, TOL, X INTEGER I, IFAIL, J * .. Local Arrays .. DOUBLE PRECISION W(IW), Y(N) * .. External Functions .. DOUBLE PRECISION D02CJW, G, X01AAF STDCALL EXTERNAL D02CJW, G, X01AAF !CHANGE * .. External Subroutines .. STDCALL EXTERNAL D02CJF, D02CJX, FCN, OUT !CHANGE * .. Intrinsic Functions .. INTRINSIC DBLE * .. Common blocks .. COMMON XEND, H, K * .. Executable Statements .. WRITE (NOUT,*) 'D02CJF Example Program Results' RELABS = "Default" !NEW XEND = 10.0D0 PI = X01AAF(0.0D0) WRITE (NOUT,*) WRITE (NOUT,*) 'Case 1: intermediate output, root-finding' DO 20 J = 4, 5 TOL = 10.0D0**(-J) WRITE (NOUT,*) WRITE (NOUT,99999) ' Calculation with TOL =', TOL X = 0.0D0 Y(1) = 0.5D0 Y(2) = 0.5D0 Y(3) = PI/5.0D0 K = 4 H = (XEND-X)/DBLE(K+1) WRITE (NOUT,*) ' X Y(1) Y(2) Y(3)' IFAIL = 0 * CALL D02CJF(X,XEND,N,Y,FCN,TOL,VAL(LOC(RELABS)),VAL(7),OUT,G,W,!CHANGE + IFAIL) * WRITE (NOUT,99998) ' Root of Y(1) = 0.0 at', X WRITE (NOUT,99997) ' Solution is', (Y(I),I=1,N) 20 CONTINUE WRITE (NOUT,*) WRITE (NOUT,*) WRITE (NOUT,*) 'Case 2: no intermediate output, root-finding' DO 40 J = 4, 5 TOL = 10.0D0**(-J) WRITE (NOUT,*) WRITE (NOUT,99999) ' Calculation with TOL =', TOL X = 0.0D0 Y(1) = 0.5D0 Y(2) = 0.5D0 Y(3) = PI/5.0D0 IFAIL = 0 * CALL D02CJF(X,XEND,N,Y,FCN,TOL,VAL(LOC(RELABS)),VAL(7),D02CJX, !CHANGE + G,W,IFAIL) * WRITE (NOUT,99998) ' Root of Y(1) = 0.0 at', X WRITE (NOUT,99997) ' Solution is', (Y(I),I=1,N) 40 CONTINUE WRITE (NOUT,*) WRITE (NOUT,*) WRITE (NOUT,*) 'Case 3: intermediate output, no root-finding' DO 60 J = 4, 5 TOL = 10.0D0**(-J) WRITE (NOUT,*) WRITE (NOUT,99999) ' Calculation with TOL =', TOL X = 0.0D0 Y(1) = 0.5D0 Y(2) = 0.5D0 Y(3) = PI/5.0D0 K = 4 H = (XEND-X)/DBLE(K+1) WRITE (NOUT,*) ' X Y(1) Y(2) Y(3)' IFAIL = 0 * CALL D02CJF(X,XEND,N,Y,FCN,TOL,VAL(LOC(RELABS)),VAL(7),OUT, CHANGE + D02CJW,W,IFAIL) * 60 CONTINUE WRITE (NOUT,*) WRITE (NOUT,*) WRITE (NOUT,*) +'Case 4: no intermediate output, no root-finding ( integrate to XE +ND)' DO 80 J = 4, 5 TOL = 10.0D0**(-J) WRITE (NOUT,*) WRITE (NOUT,99999) ' Calculation with TOL =', TOL X = 0.0D0 Y(1) = 0.5D0 Y(2) = 0.5D0 Y(3) = PI/5.0D0 WRITE (NOUT,*) ' X Y(1) Y(2) Y(3)' WRITE (NOUT,99996) X, (Y(I),I=1,N) IFAIL = 0 * CALL D02CJF(X,XEND,N,Y,FCN,TOL,VAL(LOC(RELABS)),VAL(7),D02CJX, !CHANGE + D02CJW,W,IFAIL) * WRITE (NOUT,99996) X, (Y(I),I=1,N) 80 CONTINUE STOP * 99999 FORMAT (1X,A,D8.1) 99998 FORMAT (1X,A,F7.3) 99997 FORMAT (1X,A,3F13.5) 99996 FORMAT (1X,F8.2,3F13.5) END * STDCALL SUBROUTINE OUT(X,Y) !CHANGE * .. Parameters .. INTEGER NOUT PARAMETER (NOUT=6) INTEGER N PARAMETER (N=3) * .. Scalar Arguments .. DOUBLE PRECISION X * .. Array Arguments .. DOUBLE PRECISION Y(N) * .. Scalars in Common .. DOUBLE PRECISION H, XEND INTEGER I * .. Local Scalars .. INTEGER J * .. Intrinsic Functions .. INTRINSIC DBLE * .. Common blocks .. COMMON XEND, H, I * .. Executable Statements .. WRITE (NOUT,99999) X, (Y(J),J=1,N) X = XEND - DBLE(I)*H I = I - 1 RETURN * 99999 FORMAT (1X,F8.2,3F13.5) END * STDCALL SUBROUTINE FCN(T,Y,F) !CHANGE * .. Parameters .. INTEGER N PARAMETER (N=3) * .. Scalar Arguments .. DOUBLE PRECISION T * .. Array Arguments .. DOUBLE PRECISION F(N), Y(N) * .. Intrinsic Functions .. INTRINSIC COS, TAN * .. Executable Statements .. F(1) = TAN(Y(3)) F(2) = -0.032D0*TAN(Y(3))/Y(2) - 0.02D0*Y(2)/COS(Y(3)) F(3) = -0.032D0/Y(2)**2 RETURN END * STDCALL DOUBLE PRECISION FUNCTION G(T,Y) !CHANGE * .. Parameters .. INTEGER N PARAMETER (N=3) * .. Scalar Arguments .. DOUBLE PRECISION T * .. Array Arguments .. DOUBLE PRECISION Y(N) * .. Executable Statements .. G = Y(1) RETURN END geany-2.0/tests/ctags/keyword_out.cs0000644000175000017500000000045414514252267014557 00000000000000// cs_out.cs using System; public class MyClass { public static int TestOut(out char i) { i = 'b'; return -1; } public static void Main() { char i; // variable need not be initialized Console.WriteLine(TestOut(out i)); Console.WriteLine(i); } } geany-2.0/tests/ctags/ruby-scope-after-anonymous-class.rb0000644000175000017500000000014314514252267020515 00000000000000class C class << self def foo() end end def bar(); end end puts C.foo puts C.new.bar geany-2.0/tests/ctags/bug1458930.c0000644000175000017500000000006114514252267013346 00000000000000// test with --c-kinds=+p char x(); wchar_t y(); geany-2.0/tests/ctags/extern_variable.h0000644000175000017500000000006414514252267015175 00000000000000extern int a; extern struct B b; struct S; class C; geany-2.0/tests/ctags/bug1691412.java0000644000175000017500000000073514514252267014047 00000000000000public class C { @NonNull @CheckReturnValue(explanation = "When this function returns, the caller can get the Cipher name selected by the user in the Dialog.") public static DefaultCipherDialog newInstance() { DefaultCipherDialog instance = new DefaultCipherDialog(); instance.init(); return instance; } @Override public String toString() { return "hello"; } } @Target(ElementType.METHOD) @Retention(RetentionPolicy.SOURCE) public @interface CustomAnnotation { } geany-2.0/tests/ctags/pure_elem.f950000644000175000017500000000176514514252267014165 00000000000000! elemental ! !Pure procedures are procedures declared with the PURE keyword and which !satisfy certain constraints that ensure they have no side !effects. They can be used in specification expressions and !within FORALL constructs and statements. !Elemental procedures can be written in Fortran 95 using the ELEMENTAL !keyword. Elemental procedures are automatically ``pure''. !Example: PURE REAL FUNCTION pure_func(x,y) ! pure okay IMPLICIT NONE REAL, INTENT(IN) :: x, y pure_func = x*x + y*y + 2*x*y + ASIN(MIN(x/y,y/x)) END FUNCTION pure_func PURE REAL FUNCTION F(x,y) ! pure broken returns 'PURE REAL FU' IMPLICIT NONE REAL, INTENT(IN) :: x, y F = x*x + y*y + 2*x*y + ASIN(MIN(x/y,y/x)) END FUNCTION F ELEMENTAL REAL FUNCTION elem_maxabs(a,b) ! elemental broke IMPLICIT NONE REAL,INTENT(IN) :: a,b elem_maxabs = MAX(ABS(a),ABS(b)) END PURE REAL FUNCTION pure_maxabs2(a,b) ! pure okay IMPLICIT NONE REAL,INTENT(IN) :: a,b pure_maxabs2 = MAX(ABS(a),ABS(b)) END geany-2.0/tests/ctags/intro_orig.tex0000644000175000017500000002211214514252267014545 00000000000000% http://sip.clarku.edu/tutorials/TeX/intro.html \documentclass[12pt]{article} \usepackage{amsmath} % need for subequations \usepackage{graphicx} % need for figures \usepackage{verbatim} % useful for program listings \usepackage{color} % use if color is used in text \usepackage{subfigure} % use for side-by-side figures \usepackage{hyperref} % use for hypertext links, including those to external documents and URLs % don't need the following. simply use defaults \setlength{\baselineskip}{16.0pt} % 16 pt usual spacing between lines \setlength{\parskip}{3pt plus 2pt} \setlength{\parindent}{20pt} \setlength{\oddsidemargin}{0.5cm} \setlength{\evensidemargin}{0.5cm} \setlength{\marginparsep}{0.75cm} \setlength{\marginparwidth}{2.5cm} \setlength{\marginparpush}{1.0cm} \setlength{\textwidth}{150mm} \newenvironment{boxed} {\begin{center} \begin{tabular}{|p{0.9\textwidth}|} \hline\\ } { \\\\\hline \end{tabular} \end{center} } \DeclareMathOperator{\End}{End} \newtheorem{theorem1}{Theorem} \begin{comment} \pagestyle{empty} % use if page numbers not wanted \end{comment} % above is the preamble \begin{document} \begin{center} {\large Introduction to \LaTeX} \\ % \\ = new line \copyright 2006 by Harvey Gould \\ December 5, 2006 \end{center} \section{Introduction} \TeX\ looks more difficult than it is. It is almost as easy as $\pi$. See how easy it is to make special symbols such as $\alpha$, $\beta$, $\gamma$, $\delta$, $\sin x$, $\hbar$, $\lambda$, $\ldots$ We also can make subscripts $A_{x}$, $A_{xy}$ and superscripts, $e^x$, $e^{x^2}$, and $e^{a^b}$. We will use \LaTeX, which is based on \TeX\ and has many higher-level commands (macros) for formatting, making tables, etc. More information can be found in Ref.~\cite{latex}. We just made a new paragraph. Extra lines and spaces make no difference. Note that all formulas are enclosed by \$ and occur in \textit{math mode}. The default font is Computer Modern. It includes \textit{italics}, \textbf{boldface}, \textsl{slanted}, and \texttt{monospaced} fonts. \section{Equations} Let us see how easy it is to write equations. \begin{equation} \Delta =\sum_{i=1}^N w_i (x_i - \bar{x})^2 . \end{equation} It is a good idea to number equations, but we can have a equation without a number by writing \begin{equation} P(x) = \frac{x - a}{b - a} , \nonumber \end{equation} and \begin{equation} g = \frac{1}{2} \sqrt{2\pi} . \nonumber \end{equation} We can give an equation a label so that we can refer to it later. \begin{equation} \label{eq:ising} E = -J \sum_{i=1}^N s_i s_{i+1} , \end{equation} Equation~\eqref{eq:ising} expresses the energy of a configuration of spins in the Ising model.\footnote{It is necessary to process (typeset) a file twice to get the counters correct.} We can define our own macros to save typing. For example, suppose that we introduce the macros: \begin{verbatim} \newcommand{\lb}{{\langle}} \newcommand{\rb}{{\rangle}} \end{verbatim} \newcommand{\lb}{{\langle}} \newcommand{\rb}{{\rangle}} Then we can write the average value of $x$ as \begin{verbatim} \begin{equation} \lb x \rb = 3 \end{equation} \end{verbatim} The result is \begin{equation} \lb x \rb = 3 . \end{equation} Examples of more complicated equations: \begin{equation} I = \! \int_{-\infty}^\infty f(x)\,dx \label{eq:fine}. \end{equation} We can do some fine tuning by adding small amounts of horizontal spacing: \begin{verbatim} \, small space \! negative space \end{verbatim} as is done in Eq.~\eqref{eq:fine}. We also can align several equations: \begin{align} a & = b \\ c &= d , \end{align} or number them as subequations: \begin{subequations} \begin{align} a & = b \\ c &= d . \end{align} \end{subequations} We can also have different cases: \begin{equation} \label{eq:mdiv} m(T) = \begin{cases} 0 & \text{$T > T_c$} \\ \bigl(1 - [\sinh 2 \beta J]^{-4} \bigr)^{\! 1/8} & \text{$T < T_c$} \end{cases} \end{equation} write matrices \begin{align} \textbf{T} &= \begin{pmatrix} T_{++} \hfill & T_{+-} \\ T_{-+} & T_{--} \hfill \end{pmatrix} , \nonumber \\ & = \begin{pmatrix} e^{\beta (J + B)} \hfill & e^{-\beta J} \hfill \\ e^{-\beta J} \hfill & e^{\beta (J - B)} \hfill \end{pmatrix}. \end{align} and \newcommand{\rv}{\textbf{r}} \begin{equation} \sum_i \vec A \cdot \vec B = -P\!\int\! \rv \cdot \hat{\mathbf{n}}\, dA = P\!\int \! {\vec \nabla} \cdot \rv\, dV. \end{equation} \section{Tables} Tables are a little more difficult. TeX automatically calculates the width of the columns. \begin{table}[h] \begin{center} \begin{tabular}{|l|l|r|l|} \hline lattice & $d$ & $q$ & $T_{\rm mf}/T_c$ \\ \hline square & 2 & 4 & 1.763 \\ \hline triangular & 2 & 6 & 1.648 \\ \hline diamond & 3 & 4 & 1.479 \\ \hline simple cubic & 3 & 6 & 1.330 \\ \hline bcc & 3 & 8 & 1.260 \\ \hline fcc & 3 & 12 & 1.225 \\ \hline \end{tabular} \caption{\label{tab:5/tc}Comparison of the mean-field predictions for the critical temperature of the Ising model with exact results and the best known estimates for different spatial dimensions $d$ and lattice symmetries.} \end{center} \end{table} \section{Lists} Some example of formatted lists include the following: \begin{enumerate} \item bread \item cheese \end{enumerate} \begin{itemize} \item Tom \item Dick \end{itemize} \section{Figures} We can make figures bigger or smaller by scaling them. Figure~\ref{fig:lj} has been scaled by 60\%. \begin{figure}[h] \begin{center} \includegraphics{figures/sine} \caption{\label{fig:typical}Show me a sine.} \end{center} \end{figure} \begin{figure}[h] \begin{center} \scalebox{0.6}{\includegraphics{figures/lj}} \caption{\label{fig:lj}Plot of the Lennard-Jones potential $u(r)$. The potential is characterized by a length $\sigma$ and an energy $\epsilon$.} \end{center} \end{figure} \section{Literal text} It is desirable to print program code exactly as it is typed in a monospaced font. Use \verb \begin{verbatim} and \verb \end{verbatim} as in the following example: \begin{verbatim} double y0 = 10; // example of declaration and assignment statement double v0 = 0; // initial velocity double t = 0; // time double dt = 0.01; // time step double y = y0; \end{verbatim} The command \verb \verbatiminput{programs/Square.java}\ allows you to list the file \texttt{Square.java} in the directory programs. \section{Special Symbols} \subsection{Common Greek letters} These commands may be used only in math mode. Only the most common letters are included here. $\alpha, \beta, \gamma, \Gamma, \delta,\Delta, \epsilon, \zeta, \eta, \theta, \Theta, \kappa, \lambda, \Lambda, \mu, \nu, \xi, \Xi, \pi, \Pi, \rho, \sigma, \tau, \phi, \Phi, \chi, \psi, \Psi, \omega, \Omega$ \subsection{Special symbols} The derivative is defined as \begin{equation} \frac{dy}{dx} = \lim_{\Delta x \to 0} \frac{\Delta y} {\Delta x} \end{equation} \begin{equation} f(x) \to y \quad \mbox{as} \quad x \to x_{0} \end{equation} \begin{equation} f(x) \mathop {\longrightarrow} \limits_{x \to x_0} y \end{equation} \noindent Order of magnitude: \begin{equation} \log_{10}f \simeq n \end{equation} \begin{equation} f(x)\sim 10^{n} \end{equation} Approximate equality: \begin{equation} f(x)\simeq g(x) \end{equation} \LaTeX\ is simple if we keep everything in proportion: \begin{equation} f(x) \propto x^3 . \end{equation} Finally we can skip some space by using commands such as \begin{verbatim} \bigskip \medskip \smallskip \vspace{1pc} \end{verbatim} The space can be negative. \section{\color{red}Use of Color} {\color{blue}{We can change colors for emphasis}}, {\color{green}{but}} {\color{cyan}{who is going pay for the ink?}} \section{\label{morefig}Subfigures} As soon as many students start becoming comfortable using \LaTeX, they want to use some of its advanced features. So we now show how to place two figures side by side. \begin{figure}[h!] \begin{center} \subfigure[Real and imaginary.]{ \includegraphics[scale=0.5]{figures/reim}} \subfigure[Amplitude and phase.]{ \includegraphics[scale=0.5]{figures/phase}} \caption{\label{fig:qm/complexfunctions} Two representations of complex wave functions.} \end{center} \end{figure} We first have to include the necessary package, \verb+\usepackage{subfigure}+, which has to go in the preamble (before \verb+\begin{document}+). It sometimes can be difficult to place a figure in the desired place. Your LaTeX document can be easily modified to make a poster or a screen presentation similar to (and better than) PowerPoint. Conversion to HTML is straightforward. Comments on this tutorial are appreciated. \begin{thebibliography}{5} \bibitem{latex}Helmut Kopka and Patrick W. Daly, \textsl{A Guide to \LaTeX: Document Preparation for Beginners and Advanced Users}, fourth edition, Addison-Wesley (2004). \bibitem{website}Some useful links are given at \url{}. \end{thebibliography} {\small \noindent Updated 5 December 2006.} \end{document} geany-2.0/tests/ctags/bug3571233.js.tags0000644000175000017500000000115514514252267014474 00000000000000MyClassÌ1Ö0 class: MyClass MyClassÌ16Í()Ö0 function: MyClass() function1Ì16Í()Ö0 function: function1() function2Ì16Í()Ö0 function: function2() method2Ì128Í()ÎMyClassÖ0 method: MyClass :: method2() nestedFunction1Ì16Í()ÎMyClass.method2Ö0 function: MyClass.method2 :: nestedFunction1() nestedFunction2Ì16Í()ÎMyClass.method2Ö0 function: MyClass.method2 :: nestedFunction2() nestedFunction3Ì16Í()Îfunction1Ö0 function: function1 :: nestedFunction3() nestedFunction4Ì16Í()Îfunction2Ö0 function: function2 :: nestedFunction4() nestedFunction5Ì16Í()Îfunction2Ö0 function: function2 :: nestedFunction5() geany-2.0/tests/ctags/bug823000.sql0000644000175000017500000000410714514252267013627 00000000000000/* Bugs item #823000, was opened at 2003-10-13 21:56 Message generated for change (Tracker Item Submitted) made by Item Submitter You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=106556&aid=823000&group_id=6556 Category: None Group: None Status: Open Resolution: None Priority: 5 Submitted By: Jozsef Nagy (brutal) Assigned to: Nobody/Anonymous (nobody) Summary: PL/SQL functions and procedures Initial Comment: I've tried to use ctags (version 5.5.2) to navigate PL/SQL source codes in vim but jumping to function/procedure definitions worked not properly. I figured out that the problem was that I've defined these functions/procedures in multiline format, for example: test.pkb: */ CREATE OR REPLACE PACKAGE TEST IS PROCEDURE TestFunc1 ( arg1 IN NUMBER, arg2 IN NUMBER ) IS BEGIN NULL; END TestFunc1; PROCEDURE TestFunc2 ( arg1 IN NUMBER, arg2 IN NUMBER ) IS BEGIN NULL; END TestFunc2; END TEST; / /* ctags creates a regexp type pattern for my functions/procedures but unfortunately the pattern was /^IS$/ for each function/procedure, that's why the jumping method worked really crappy. (see the output of ctags 5.5.2 on this example code below) ctags -f - --language-force=sql test.pkb TEST test.pkb /^CREATE OR REPLACE PACKAGE TEST IS$/;" P TestFunc1 test.pkb /^IS$/;" p TestFunc2 test.pkb /^IS$/;" p I've looked into the ctags source code and I saw that in parseSubProgram() in sql.c called makeSqlTag() only when KEYWORD_is reached. I have modified this function so that makeSqlTag() is called immediately after a function/procedure keyword and name is read (I have attached the output of diff sql.c.5.5.2 sql.c). I don't know much of ctags internals so I am not sure if this is the best solution but it worked for me. (see the output of my modified ctags below) ctags -f - --language-force=sql test.pkb TEST test.pkb /^CREATE OR REPLACE PACKAGE TEST IS$/;" P TestFunc1 test.pkb /^PROCEDURE TestFunc1$/;" p TestFunc2 test.pkb /^PROCEDURE TestFunc2$/;" p */ geany-2.0/tests/ctags/bug1906062.py.tags0000644000175000017500000000011214514252267014500 00000000000000dummyÌ1Ö0 class: dummy include_fileÌ16384Ö0 variable: include_file geany-2.0/tests/ctags/Package.pm0000644000175000017500000000102314514252267013537 00000000000000# This file is intended to test package keyword support along with # multi-line subroutine definitions, like this: # sub # # somefunction # {... package Test::One; package Test::One::Two; package Test; use strict; use warnings; sub init { } use constant CONST => 1; =head2 quo This is 'quo' subroutine =cut sub quo; quo; Test::quo; sub quo { goto END; die; END: END2 : print "END!\n"; return; } sub xuz :lvalue; sub xtz (&@;$) :lvalue; sub # This should create a tag dude { 1; } 1; geany-2.0/tests/ctags/misc_types.f900000644000175000017500000000150014514252267014345 00000000000000! Provided by Brian Helsinki, 7 March 2003 program testalloc integer base_type automatic foobar_var ! automatic breaks parsing integer i2 static s_var ! static breaks parsing integer i3 volatile v_var ! volatile breaks var parsing integer i4 DLL_IMPORT foobar2 ! break var parsing DLL_EXPORT foobar ! breaks var parsing integer i5 common foobar_var, s_var, v_var integer i6 structure /my_struct/ integer(1) :: first_byte integer(1) :: %fill integer(2) :: align_second_16 end structure integer i7 record /m_struct/ the_struct ! break var parsing integer i8 real, dimension (:), allocatable :: list ! allocatable integer i, status i = 99 allocate (list(i), stat=status ) ! create array allocate list (1) = 1.2 deallocate (list) ! deallocate do i=1,100 j=i end do stop end geany-2.0/tests/ctags/keyword_enum.cs0000644000175000017500000000125314514252267014712 00000000000000// C# Programmer's Reference: enum // keyword_enum.cs // enum initialization: using System; public class EnumTest { enum Days {Sat=1, Sun, Mon, Tue, Wed, Thu, Fri}; public static void Main() { int x = (int) Days.Sun; int y = (int) Days.Fri; Console.WriteLine("Sun = {0}", x); Console.WriteLine("Fri = {0}", y); } } // keyword_enum2.cs // Using long enumerators using System; public class EnumTest { enum Range :long {Max = 2147483648L, Min = 255L}; public static void Main() { long x = (long) Range.Max; long y = (long) Range.Min; Console.WriteLine("Max = {0}", x); Console.WriteLine("Min = {0}", y); } } geany-2.0/tests/ctags/keyword_catch_try.cs.tags0000644000175000017500000000031014514252267016654 00000000000000MainÌ128Í()ÎMyClassÖ0Ïpublic void method: public void MyClass :: Main() MyClassÌ1Ö0 class: MyClass MyFnÌ128Í(string s)ÎMyClassÖ0Ïpublic void method: public void MyClass :: MyFn(string s) geany-2.0/tests/ctags/bug1830343.cs0000644000175000017500000000026714514252267013531 00000000000000class ForEachTest { static void Main(string[] args) { int[] fibarray = new int[] { 0, 1, 2, 3, 5, 8, 13 }; foreach (int i in fibarray) { System.Console.WriteLine(i); } } } geany-2.0/tests/ctags/simple.conf.tags0000644000175000017500000000246014514252267014751 00000000000000argsÌ65536Îhandler_hand01Ö0 macro: handler_hand01 :: args classÌ65536Îformatter_form01Ö0 macro: formatter_form01 :: class classÌ65536Îhandler_hand01Ö0 macro: handler_hand01 :: class datefmtÌ65536Îformatter_form01Ö0 macro: formatter_form01 :: datefmt formatÌ65536Îformatter_form01Ö0 macro: formatter_form01 :: format formatterÌ65536Îhandler_hand01Ö0 macro: handler_hand01 :: formatter formatter_form01Ì256Ö0 namespace: formatter_form01 formattersÌ256Ö0 namespace: formatters handler_hand01Ì256Ö0 namespace: handler_hand01 handlersÌ256Ö0 namespace: handlers handlersÌ65536Îlogger_parserÖ0 macro: logger_parser :: handlers handlersÌ65536Îlogger_rootÖ0 macro: logger_root :: handlers keysÌ65536ÎformattersÖ0 macro: formatters :: keys keysÌ65536ÎhandlersÖ0 macro: handlers :: keys keysÌ65536ÎloggersÖ0 macro: loggers :: keys levelÌ65536Îhandler_hand01Ö0 macro: handler_hand01 :: level levelÌ65536Îlogger_parserÖ0 macro: logger_parser :: level levelÌ65536Îlogger_rootÖ0 macro: logger_root :: level logger_parserÌ256Ö0 namespace: logger_parser logger_rootÌ256Ö0 namespace: logger_root loggersÌ256Ö0 namespace: loggers propagateÌ65536Îlogger_parserÖ0 macro: logger_parser :: propagate qualnameÌ65536Îlogger_parserÖ0 macro: logger_parser :: qualname geany-2.0/tests/ctags/simple.tcl0000644000175000017500000000101514514252267013644 00000000000000oo::class create X { superclass Y; method add v { }; method doSomething {v} { } } class create ShouldNotBeCaptured { } proc simple1 {} { } namespace eval A::B { } namespace eval A { proc pr1 {s} { puts $s } pr1 "a" proc B::pr2 {s} { puts "$s" } namespace eval C { proc pr3 {s} { puts $s } } proc ::pr4 {s} { puts "$s" } } proc ::pr5 {s} { puts "$s" } proc pr6 {s} { puts "$s" } A::pr1 "b" A::B::pr2 "c" A::C::pr3 "d" pr4 "e" pr5 "f" pr6 "g" geany-2.0/tests/ctags/prototype.h0000644000175000017500000000010214514252267014061 00000000000000int prototype_a (int a, char *b); extern void prototype_b (void); geany-2.0/tests/ctags/bug1020715.cpp.tags0000644000175000017500000000004414514252267014626 00000000000000fÌ16Í()Ö0Ïvoid function: void f() geany-2.0/tests/ctags/simple.zep.tags0000644000175000017500000000034314514252267014620 00000000000000MyClassÌ1ÎTestÖ0 class: Test :: MyClass TestÌ256Ö0 namespace: Test someMethod1Ì16Í()ÎTest::MyClassÖ0 function: Test::MyClass :: someMethod1() someMethod2Ì16Í()ÎTest::MyClassÖ0 function: Test::MyClass :: someMethod2() geany-2.0/tests/ctags/interface_indexers.cs.tags0000644000175000017500000000042214514252267016775 00000000000000IMyInterfaceÌ32Ö0 interface: IMyInterface IndexerClassÌ1Ö0 class: IndexerClass MainÌ128Í()ÎMainClassÖ0Ïpublic void method: public void MainClass :: Main() MainClassÌ1Ö0 class: MainClass myArrayÌ8ÎIndexerClassÖ0Ïint[] field: int[] IndexerClass :: myArray geany-2.0/tests/ctags/bug762027.v.tags0000644000175000017500000000007414514252267014244 00000000000000N_83Ì16384Ö0 variable: N_83 N_84Ì16384Ö0 variable: N_84 geany-2.0/tests/ctags/extern_variable.h.tags0000644000175000017500000000007414514252267016133 00000000000000aÌ32768Ö0Ïint externvar: int a bÌ32768Ö0ÏB externvar: B b geany-2.0/tests/ctags/ada-ads.ads0000644000175000017500000000334414514252267013641 00000000000000-- Object-oriented generalized stack. This illustrates the use of a -- controlled type, which is one that has construction and destructions. -- It also shows how to create two related types in the same package so -- that they can share private declarations. This sort of thing is -- accomplished in Java or C++ using nested classes, or using friend -- declarations in C++. -- with Ada.Finalization; use Ada.Finalization; package GenStack is -- This is the stack type. type Stack is new Controlled with private; -- This is the base type for nodes. Client packages must derive their -- nodes from StackData. Since it comes from Controlled, the user can -- override the Initialize, Adjust, and Finalize methods as needed. type StackData is new Controlled with null record; -- Initialization operations. procedure Initialize(S: in out Stack); procedure Adjust(S: in out Stack); procedure Finalize(S: in out Stack); -- Stack operations. procedure Push(S: in out Stack; D: StackData'class); procedure Pop(S: in out Stack; D: in out StackData'class); procedure Top(S: Stack; Data: in out StackData'class); function Empty(S: Stack) return Boolean; private -- Pointer to the node type. type Node; type Node_Ptr is access Node; -- Here is the generalized stack itself. We would just make it the -- pointer itself, but it needs to be a record so it can be in a with. type Stack is new Controlled with record Head: Node_Ptr; end record; -- Now, we need a pointer to the data part. type Data_Ptr is access StackData'Class; -- This is the node type. type Node is record Data: Data_Ptr; Next: Node_Ptr; end record; end GenStack; geany-2.0/tests/ctags/bug2374109.vhd.tags0000644000175000017500000000011214514252267014633 00000000000000Pow2Ì16Ö0 function: Pow2 ResultÌ16384ÎPow2Ö0 variable: Pow2 :: Result geany-2.0/tests/ctags/bug612019.pas0000644000175000017500000000124314514252267013617 00000000000000(* Bugs item #612019, was opened at 2002-09-20 15:29 You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=106556&aid=612019&group_id=6556 Category: None Group: None Status: Open Resolution: None Priority: 5 Submitted By: Konstantin Stupnik (xecutor) Assigned to: Nobody/Anonymous (nobody) Summary: pascal parser Initial Comment: In attached sample there are some lines from tags file generated for object pascal sources. There are some problems with this lines. Generally speaking they are parsed incorrectly. *) unit a; interface type TTest=class procedure Test1; procedure Test2; procedure Test3; end; implementation end. geany-2.0/tests/ctags/return-types.go.tags0000644000175000017500000000071414514252267015621 00000000000000barÌ16Í()ÎmainÖ0Ï(a int, b func(a int), c interface{}, d string) function: (a int, b func(a int), c interface{}, d string) main :: bar() bazÌ16Í()ÎmainÖ0Ï*[20*3+1]map[chan<- <-chan int]map[interface{}]*string function: *[20*3+1]map[chan<- <-chan int]map[interface{}]*string main :: baz() fooÌ16Í()ÎmainÖ0Ï*struct {a int; b func()} function: *struct {a int; b func()} main :: foo() mainÌ16Í()ÎmainÖ0 function: main :: main() mainÌ256Ö0 namespace: main geany-2.0/tests/ctags/arraylist.js0000644000175000017500000000047614514252267014231 00000000000000 var a = []; var b = [1, 2, 3]; var c = [ { a: "hello", b: 42 }, { a: "hi", b: 41 } ]; var class = function() { this.test1 = { foo: [ 1, 2, 3], bar: [ 4, 5, 9] }; // FIXME: no tag is generated for test2 this.test2 = [ { a: {}, b: {} }, { a: {}, b: {} } ]; this.test3 = function() {} } geany-2.0/tests/ctags/test.go.tags0000644000175000017500000000364314514252267014123 00000000000000AÌ65536ÎmainÖ0 macro: main :: A BÌ65536ÎmainÖ0 macro: main :: B CÌ65536ÎmainÖ0 macro: main :: C DÌ65536ÎmainÖ0 macro: main :: D EÌ65536ÎmainÖ0 macro: main :: E FÌ65536ÎmainÖ0 macro: main :: F GÌ65536ÎmainÖ0 macro: main :: G HÌ65536ÎmainÖ0 macro: main :: H IÌ65536ÎmainÖ0 macro: main :: I T1Ì4096ÎmainÖ0Ïmap[string]int typedef: map[string]int main :: T1 T2Ì4096ÎmainÖ0Ï<-chan float32 typedef: <-chan float32 main :: T2 T3Ì4096ÎmainÖ0Ïchan []string typedef: chan []string main :: T3 T4Ì4096ÎmainÖ0Ïchan<- *[12]string typedef: chan<- *[12]string main :: T4 T5Ì32ÎmainÖ0 interface: main :: T5 T6Ì2048ÎmainÖ0 struct: main :: T6 T7Ì4096ÎmainÖ0Ïfunc (a struct{_ int; _ float32}, b int) (int, map[string]int) typedef: func (a struct{_ int; _ float32}, b int) (int, map[string]int) main :: T7 T8Ì4096ÎmainÖ0Ïfloat32 typedef: float32 main :: T8 T9Ì4096ÎmainÖ0Ïint typedef: int main :: T9 _aÌ64Îmain.T6Ö0Ïint member: int main.T6 :: _a _bÌ64Îmain.T6Ö0Ïint member: int main.T6 :: _b _cÌ64Îmain.T6Ö0Ïint member: int main.T6 :: _c _dÌ64Îmain.T6Ö0Ïint member: int main.T6 :: _d _eÌ64Îmain.T6Ö0Ïfloat32 member: float32 main.T6 :: _e aÌ16384ÎmainÖ0Ïint variable: int main :: a bÌ16384ÎmainÖ0Ïint variable: int main :: b cÌ16384ÎmainÖ0Ïint variable: int main :: c dÌ16384ÎmainÖ0ÏT5 variable: T5 main :: d eÌ16384ÎmainÖ0ÏT4 variable: T4 main :: e fÌ16384ÎmainÖ0Ïinterface{} variable: interface{} main :: f f1Ì16Í()ÎmainÖ0 function: main :: f1() f2Ì16Í()ÎmainÖ0 function: main :: f2() f3Ì16Í()Îmain.T1Ö0Ï(a, b int) function: (a, b int) main.T1 :: f3() f4Ì16Í(a func () func ())Îmain.T7Ö0Ï(func (), int) function: (func (), int) main.T7 :: f4(a func () func ()) f5Ì16Í()ÎmainÖ0 function: main :: f5() gÌ16384ÎmainÖ0Ïint variable: int main :: g hÌ16384ÎmainÖ0Ïint variable: int main :: h mainÌ16Í()ÎmainÖ0 function: main :: main() mainÌ256Ö0 namespace: main geany-2.0/tests/ctags/simple.lisp0000644000175000017500000000037514514252267014041 00000000000000(defun a0 (n) (+ 1 n)) (DEFUN A1 (n) (+ 2 n)) (defvar b0 3) (DEFVAR B1 4) (defconstant c0 5) (DEFCONSTANT C1 6) (defmacro defunknown0 (s) `(defconstant ,s 'unknown)) (DEFMACRO DEFUNKNOWN1 (s) `(defconstant ,s 'unknown)) (defunknown1 unknown) geany-2.0/tests/ctags/simple.asciidoc0000644000175000017500000000137414514252267014650 00000000000000= Chapter 1 (Level 0) Intro text of chapter 1 == Section 1.1 Text of section 1.1 === Subsection 1.1.1 Text of subsection 1.1.1 ==== Level 3 Section 1.1.1.1 Title Text of subsection 1.1.1.1 ===== Level 4 Section 1.1.1.1.1 Title Text of subsection 1.1.1.1.1 ====== Level 5 Section 1.1.1.1.1.1 Title Text of subsection 1.1.1.1.1.1 == Section 1.2 Text of section 1.2 // and now two-line titles: Chapter 2 ========= Intro text of chapter 2 Section 2.1 ------------ Text of section 2.1 Subsection 2.1.1 ~~~~~~~~~~~~~~~ Level 3 Section 2.1.1.1 Title ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Text of subsection 2.1.1.1 Level 4 Section 2.1.1.1.1 Title +++++++++++++++++++++++++++++++ Text of subsection 2.1.1.1.1 Section 2.2 ----------- Text of section 2.2 geany-2.0/tests/ctags/css-trivial.css.tags0000644000175000017500000000021714514252267015561 00000000000000aÌ2048Ö0 struct: a htmlÌ2048Ö0 struct: html inputÌ2048Ö0 struct: input pÌ2048Ö0 struct: p textareaÌ2048Ö0 struct: textarea geany-2.0/tests/ctags/return-hint.zep.tags0000644000175000017500000000035514514252267015611 00000000000000TestÌ1Ö0 class: Test firstÌ16Í(string str)ÎTestÖ0Ïstring function: string Test :: first(string str) nestedÌ16Í()ÎTest::firstÖ0 function: Test::first :: nested() secondÌ16Í(int i)ÎTestÖ0Ïint function: int Test :: second(int i) geany-2.0/tests/ctags/geany.nsi.tags0000644000175000017500000000164414514252267014432 00000000000000!Program FilesÌ256Ö0 namespace: !Program Files -AdditionalIconsÌ256Ö0 namespace: -AdditionalIcons -PostÌ256Ö0 namespace: -Post .onInitÌ16Ö0 function: .onInit AnswerÌ16384Ö0 variable: Answer Autocompletion TagsÌ256Ö0 namespace: Autocompletion Tags Context MenusÌ256Ö0 namespace: Context Menus Desktop ShortcutsÌ256Ö0 namespace: Desktop Shortcuts Development filesÌ256Ö0 namespace: Development files DocumentationÌ256Ö0 namespace: Documentation GTK ${GTK_VERSION} Runtime EnvironmentÌ256Ö0 namespace: GTK ${GTK_VERSION} Runtime Environment Language FilesÌ256Ö0 namespace: Language Files OnDirLeaveÌ16Ö0 function: OnDirLeave PluginsÌ256Ö0 namespace: Plugins StartmenuFolderÌ16384Ö0 variable: StartmenuFolder UNINSTDIRÌ16384Ö0 variable: UNINSTDIR UninstallÌ256Ö0 namespace: Uninstall UserNameÌ16384Ö0 variable: UserName un.onInitÌ16Ö0 function: un.onInit un.onUninstSuccessÌ16Ö0 function: un.onUninstSuccess geany-2.0/tests/ctags/c-digraphs.c.tags0000644000175000017500000000077614514252267015006 00000000000000AÌ65536Ö0 macro: A BÌ65536Ö0 macro: B M3_INITÌ131072Í(a,b,c)Ö0 macro_arg: M3_INIT(a,b,c) STRINGIFYÌ131072Í(x)Ö0 macro_arg: STRINGIFY(x) STRINGIFY_INTERNÌ131072Í(x)Ö0 macro_arg: STRINGIFY_INTERN(x) bufÌ64ÎstrÖ0Ïchar * member: char * str :: buf lenÌ64ÎstrÖ0Ïunsigned int member: unsigned int str :: len mainÌ16Í(void)Ö0Ïint function: int main(void) matrix3Ì4096Ö0Ïint[3] typedef: int[3] matrix3 sizeÌ64ÎstrÖ0Ïunsigned int member: unsigned int str :: size strÌ2048Ö0 struct: str geany-2.0/tests/ctags/cxx11-raw-strings.cpp0000644000175000017500000000126414514252267015603 00000000000000 static const char* str1 = R"blah( lots of text )blah"; struct typ1 { int memb1; }; static const char* str2 = R"blah( lots of text including a quote" )blah"; struct typ2 { int memb2; }; /* check we don't get confused by string concatenation */ #define FOUR "four" static const char* str3 = FOUR"f(iv)e"; struct typ3 { int memb3; }; /* check for prefixes */ static const char* str4 = LR"blah(";int bug4;)blah"; struct typ4 { int memb4; }; static const char* str5 = u8R"blah(";int bug5;)blah"; struct typ5 { int memb5; }; static const char* str6 = uR"blah(";int bug6;)blah"; struct typ6 { int memb6; }; static const char* str7 = UR"blah(";int bug7;)blah"; struct typ7 { int memb7; }; geany-2.0/tests/ctags/signature.cpp0000644000175000017500000000027514514252267014363 00000000000000/* Tests for collection of signature */ void foo (int a, char b) {} int bar (a, b) int a; char b; {} char *BAR::bar (char *c, double d[]) const {} void foobar __ARGS ((int a, char b)); geany-2.0/tests/ctags/gdscript-no-implicit-class.gd0000644000175000017500000000337114514252267017336 00000000000000# Derived from https://docs.godotengine.org/en/latest/tutorials/scripting/gdscript/gdscript_basics.html # A file is a class but it has no name. The name is given only when # class_name is used. # Inheritance extends BaseClass # (optional) class definition with a custom icon class_name MyClass, "res://path/to/optional/icon.svg" # Signals signal sig # Member variables @export_range(start=0, end=100, step=1) var a = 5 @export var s = "Hello" @onready var arr = [1, 2, 3] var dict = {"key": "value", 2: 3} var typed_var: int @onready @export_multiline var\ inferred_type\ :=\ "String" # Constants const ANSWER = 42 const THE_NAME:String = "Charly" # Enums enum {UNIT_NEUTRAL, UNIT_ENEMY, UNIT_ALL} enum Named {THING_1, THING_2, ANOTHER_THING=1} # Built-in vector types var v2 = Vector2(1, 2) var v3 = Vector3(1, 2, 3) # Function @master func some_function(param1: Vector3, param2: int) -> int: var local_var = 5 if param1 < local_var: print(param1) elif param2 > 5: print(param2) elif param2 == 2: print(20) elif param2 <= 2: print((-20 % 3) / 5) else: print("Fail!") for i in range(20): print(i) while param2 != 0: param2 -= 1 var local_var2 = param1 + 3 return local_var2 # Functions override functions with the same name on the base/parent class. # If you still want to call them, use '.' (like 'super' in other languages). @puppet func something(p1, p2): .something(p1, p2) # Inner class class Something: var a = 10 const _private_var:String = "hi\n\\escape" func foooooooo() -> String: print(""" test\\ test""") return "" # Constructor func _init(): print("Constructed!") var lv = Something.new() print(lv.a) geany-2.0/tests/ctags/gdscript-modifiers.gd0000644000175000017500000000157514514252267015774 00000000000000# Taken from godot-demo-projects/3d/voxel/world/chunk.gd func _create_block_collider(block_sub_position): var collider = CollisionShape.new() collider.shape = BoxShape.new() collider.shape.extents = Vector3.ONE / 2 collider.transform.origin = block_sub_position + Vector3.ONE / 2 add_child(collider) static func calculate_block_uvs(block_id): # This method only supports square texture sheets. var row = block_id / TEXTURE_SHEET_WIDTH var col = block_id % TEXTURE_SHEET_WIDTH return [ TEXTURE_TILE_SIZE * Vector2(col, row), TEXTURE_TILE_SIZE * Vector2(col, row + 1), TEXTURE_TILE_SIZE * Vector2(col + 1, row), TEXTURE_TILE_SIZE * Vector2(col + 1, row + 1), ] func id(a): return a remote func r(b): return b remote static func x(c): return c geany-2.0/tests/ctags/masm.asm.tags0000644000175000017500000000062414514252267014250 00000000000000BYTE_BUFFERÌ256Ö0 namespace: BYTE_BUFFER LabelMaker1Ì256Ö0 namespace: LabelMaker1 LabelMaker2Ì256Ö0 namespace: LabelMaker2 MsgÌ65536Ö0 macro: Msg QUACKÌ256Ö0 namespace: QUACK WORD_BUFFERÌ65536Ö0 macro: WORD_BUFFER hllequalÌ65536Ö0 macro: hllequal myequÌ65536Ö0 macro: myequ myequalÌ65536Ö0 macro: myequal mymacroÌ16Ö0 function: mymacro mystructÌ2048Ö0 struct: mystruct geany-2.0/tests/ctags/bug1988027.py0000644000175000017500000000030314514252267013560 00000000000000#!/usr/bin/env python # encoding: utf-8 """ bla #""" """make a tarball with all the sources in it; return (distdirname, tarballname)""" # dummy class to generate a tag class dummy: pass geany-2.0/tests/ctags/byte.f0000644000175000017500000000021214514252267012757 00000000000000! Provided by Brian Helsinki, 7 March 2003 program byte_test BYTE A, B, C BYTE A1, B1, C1(10) BYTE A2 /'x'/, B2 /255/, C2(10) END geany-2.0/tests/ctags/Makefile.in0000644000175000017500000012730514514252336013724 00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ TESTS = $(am__EXEEXT_3) subdir = tests/ctags ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx_17.m4 \ $(top_srcdir)/m4/geany-binreloc.m4 \ $(top_srcdir)/m4/geany-docutils.m4 \ $(top_srcdir)/m4/geany-doxygen.m4 \ $(top_srcdir)/m4/geany-gtk.m4 \ $(top_srcdir)/m4/geany-gtkdoc-header.m4 \ $(top_srcdir)/m4/geany-lib.m4 \ $(top_srcdir)/m4/geany-mac-integration.m4 \ $(top_srcdir)/m4/geany-mingw.m4 \ $(top_srcdir)/m4/geany-plugins.m4 \ $(top_srcdir)/m4/geany-prog-cxx.m4 \ $(top_srcdir)/m4/geany-revision.m4 \ $(top_srcdir)/m4/geany-socket.m4 \ $(top_srcdir)/m4/geany-status.m4 \ $(top_srcdir)/m4/geany-the-force.m4 \ $(top_srcdir)/m4/geany-utils.m4 $(top_srcdir)/m4/geany-vte.m4 \ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/iconv.m4 \ $(top_srcdir)/m4/intlmacosx.m4 $(top_srcdir)/m4/lib-ld.m4 \ $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \ $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(dist_check_SCRIPTS) \ $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__tty_colors_dummy = \ mgn= red= grn= lgn= blu= brg= std=; \ am__color_tests=no am__tty_colors = { \ $(am__tty_colors_dummy); \ if test "X$(AM_COLOR_TESTS)" = Xno; then \ am__color_tests=no; \ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ am__color_tests=yes; \ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ am__color_tests=yes; \ fi; \ if test $$am__color_tests = yes; then \ red=''; \ grn=''; \ lgn=''; \ blu=''; \ mgn=''; \ brg=''; \ std=''; \ fi; \ } am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__recheck_rx = ^[ ]*:recheck:[ ]* am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* # A command that, given a newline-separated list of test names on the # standard input, print the name of the tests that are to be re-run # upon "make recheck". am__list_recheck_tests = $(AWK) '{ \ recheck = 1; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ { \ if ((getline line2 < ($$0 ".log")) < 0) \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ { \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ { \ break; \ } \ }; \ if (recheck) \ print $$0; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # A command that, given a newline-separated list of test names on the # standard input, create the global log from their .trs and .log files. am__create_global_log = $(AWK) ' \ function fatal(msg) \ { \ print "fatal: making $@: " msg | "cat >&2"; \ exit 1; \ } \ function rst_section(header) \ { \ print header; \ len = length(header); \ for (i = 1; i <= len; i = i + 1) \ printf "="; \ printf "\n\n"; \ } \ { \ copy_in_global_log = 1; \ global_test_result = "RUN"; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".trs"); \ if (line ~ /$(am__global_test_result_rx)/) \ { \ sub("$(am__global_test_result_rx)", "", line); \ sub("[ ]*$$", "", line); \ global_test_result = line; \ } \ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ copy_in_global_log = 0; \ }; \ if (copy_in_global_log) \ { \ rst_section(global_test_result ": " $$0); \ while ((rc = (getline line < ($$0 ".log"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".log"); \ print line; \ }; \ printf "\n"; \ }; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # Restructured Text title. am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } # Solaris 10 'make', and several other traditional 'make' implementations, # pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it # by disabling -e (using the XSI extension "set +e") if it's set. am__sh_e_setup = case $$- in *e*) set +e;; esac # Default flags passed to test drivers. am__common_driver_flags = \ --color-tests "$$am__color_tests" \ --enable-hard-errors "$$am__enable_hard_errors" \ --expect-failure "$$am__expect_failure" # To be inserted before the command running the test. Creates the # directory for the log if needed. Stores in $dir the directory # containing $f, in $tst the test, in $log the log. Executes the # developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and # passes TESTS_ENVIRONMENT. Set up options for the wrapper that # will run the test scripts (or their associated LOG_COMPILER, if # thy have one). am__check_pre = \ $(am__sh_e_setup); \ $(am__vpath_adj_setup) $(am__vpath_adj) \ $(am__tty_colors); \ srcdir=$(srcdir); export srcdir; \ case "$@" in \ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ *) am__odir=.;; \ esac; \ test "x$$am__odir" = x"." || test -d "$$am__odir" \ || $(MKDIR_P) "$$am__odir" || exit $$?; \ if test -f "./$$f"; then dir=./; \ elif test -f "$$f"; then dir=; \ else dir="$(srcdir)/"; fi; \ tst=$$dir$$f; log='$@'; \ if test -n '$(DISABLE_HARD_ERRORS)'; then \ am__enable_hard_errors=no; \ else \ am__enable_hard_errors=yes; \ fi; \ case " $(XFAIL_TESTS) " in \ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ am__expect_failure=yes;; \ *) \ am__expect_failure=no;; \ esac; \ $(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) # A shell command to get the names of the tests scripts with any registered # extension removed (i.e., equivalently, the names of the test logs, with # the '.log' extension removed). The result is saved in the shell variable # '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, # we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", # since that might cause problem with VPATH rewrites for suffix-less tests. # See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. am__set_TESTS_bases = \ bases='$(TEST_LOGS)'; \ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ bases=`echo $$bases` AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)' RECHECK_LOGS = $(TEST_LOGS) AM_RECURSIVE_TARGETS = check recheck am__EXEEXT_1 = am__EXEEXT_2 = 1795612.js.tags 1850914.js.tags 1878155.js.tags \ 1880687.js.tags 2023624.js.tags 3184782.sql.tags \ 3470609.js.tags 3526726.tex.tags 68hc11.asm.tags \ actionscript/as-first-token.as.tags \ actionscript/classes.as.tags actionscript/const2.as.tags \ actionscript/const.as.tags \ actionscript/method-attributes.as.tags \ actionscript/packages.as.tags actionscript/sampler.as.tags \ ada-adb.adb.tags ada-ads.ads.tags \ ada-expression-function.adb.tags \ ada-expression-function-generic.adb.tags \ ada-overriding.ads.tags ada-package-generic.ads.tags \ ada-task.adb.tags angle_bracket.cpp.tags \ anonymous_functions.php.tags arraylist.js.tags \ array_ref_and_out.cs.tags array_spec.f90.tags \ array-spec.f90.tags attributes.cs.tags auto.f.tags \ backslashes.c.tags bit_field.c.tags block.f90.tags \ bracematch.js.tags bug1020715.cpp.tags bug1020715.c.tags \ bug1086609.c.tags bug1093123.cpp.tags bug1111214-j-chan.v.tags \ bug1111214.v.tags bug1201689.c.tags bug1447756.java.tags \ bug1458930.c.tags bug1466117.c.tags bug1491666.c.tags \ bug1515910.cs.tags bug1548443.cpp.tags bug1563476.cpp.tags \ bug1570779.sql.tags bug1575055.cpp.tags bug1585745.cpp.tags \ bug1611054.cs.tags bug1691412.java.tags bug1742588.rb.tags \ bug1743330.v.tags bug1764143.h.tags bug1764148.py.tags \ bug1770479.cpp.tags bug1773926.cpp.tags bug1777344.java.tags \ bug1799340.cpp.tags bug1799343-1.cpp.tags \ bug1799343-2.cpp.tags bug1800065.cs.tags bug1809024.py.tags \ bug1830343.cs.tags bug1830344.cs.tags bug1856363.py.tags \ bug1906062.py.tags bug1907083.cpp.tags bug1924919.cpp.tags \ bug1938565.sql.tags bug1944150.sql.tags bug1950327.js.tags \ bug1988026.py.tags bug1988027.py.tags bug1988130.py.tags \ bug2049723.java.tags bug2075402.py.tags bug2117073.java.tags \ bug2374109.vhd.tags bug2411878.cs.tags bug2747828.v.tags \ bug2777310.js.tags bug2781264.rb.tags bug2886870.tex.tags \ bug2888482.js.tags bug3036476.js.tags bug3168705.py.tags \ bug3571233.js.tags bug507864.c.tags bug538629.asm.tags \ bug556645.c.tags bug556646.c.tags bug565813.f90.tags \ bug612019.pas.tags bug612621.pl.tags bug620288.f.tags \ bug639639.h.tags bug639644.hpp.tags bug665086.cpp.tags \ bug670433.f90.tags bug699171.py.tags bug722501.sql.tags \ bug726712.f90.tags bug726875.f90.tags bug734933.f90.tags \ bug762027.v.tags bug814263.java.tags bug823000.sql.tags \ bug842077.pl.tags bug849591.cpp.tags bug852368.cpp.tags \ bug858165.f90.tags bug872494.cpp.tags bug877956.f90.tags \ bug960316.v.tags bug961001.v.tags byte.f.tags \ c-digraphs.c.tags c-trigraphs.c.tags case_sensitivity.php.tags \ char-selector.f90.tags classes.php.tags \ cobol/helloworld.cbl.tags cobol/helloworld2.cbl.tags \ cobol/levels.cbl.tags cobol/quoted-program-id.cbl.tags \ cobol/simple.cbl.tags common.f.tags complex-return.js.tags \ continuation.f90.tags continuation.mak.tags countall.sql.tags \ cpp_destructor.cpp.tags css-at-rules.css.tags \ css-at-supports.css.tags css-attribute-selectors.css.tags \ css-comma-no-space.css.tags css-namespace-selectors.css.tags \ css-pseudo-classes.css.tags css-simple.css.tags \ css-singlequote-in-comment-issue2.css.tags \ css-tag-types.css.tags css-trivial.css.tags \ cython_sample.pyx.tags cython_sample2.pyx.tags \ cxx11enum.cpp.tags cxx11-final.cpp.tags \ cxx11-noexcept.cpp.tags cxx11-override.cpp.tags \ cxx11-raw-strings.cpp.tags cxx14-combined.cpp.tags \ db-trig.sql.tags debian_432872.f90.tags directives.c.tags \ dopbl2.f.tags dotted-names.json.tags enum.c.tags enum.f90.tags \ enum.java.tags enumerators.f90.tags events.cs.tags \ extern_variable.h.tags forall_module.f90.tags format.pl.tags \ fortran_associate.f90.tags fortran_line_continuation.f90.tags \ func_typedef.h.tags gdscript-inner-class.gd.tags \ gdscript-modifiers.gd.tags gdscript-no-implicit-class.gd.tags \ geany.nsi.tags general.cs.tags hex2dec.sql.tags \ implied_program.f.tags indexer.cs.tags infinite_loop.java.tags \ ingres_procedures.sql.tags initialization.f90.tags \ interface_indexers.cs.tags interface_properties.cs.tags \ interfaces.f90.tags internal.cs.tags intro_orig.tex.tags \ intro.tex.tags invalid_name.f90.tags java_enum.java.tags \ js-broken-strings.js.tags \ js-class-related-unterminated.js.tags js-const.js.tags \ js-implicit-semicolons.js.tags js-let.js.tags js-scope.js.tags \ js-signature.js.tags js-string-continuation.js.tags \ js-sub-block-scope.js.tags \ js-unknown-construct-nesting.js.tags \ julia-corner_cases.jl.tags jsFunc_tutorial.js.tags \ keyword_abstract.cs.tags keyword_catch_try.cs.tags \ keyword_class.cs.tags keyword_const.cs.tags \ keyword_delegate.cs.tags keyword_enum.cs.tags \ keyword_event.cs.tags keyword_explicit.cs.tags \ keyword_extern.cs.tags keyword_implicit.cs.tags \ keyword_interface.cs.tags keyword_namespace.cs.tags \ keyword_names.f90.tags keyword_out.cs.tags \ keyword_override.cs.tags keyword_params.cs.tags \ keyword_private.cs.tags keyword_protected.cs.tags \ keyword_public.cs.tags keyword_sealed.cs.tags \ keyword_static.cs.tags keyword_struct.cs.tags \ keyword_virtual.cs.tags keyword_volatile.cs.tags \ labels.sql.tags lanus.for.tags line_directives.c.tags \ local.c.tags macros.c.tags make-comment-in-rule.mak.tags \ make-gnumake-pattern-rules.mak.tags make-multi-target.mak.tags \ make-parentheses.mak.tags \ make-target-with-parentheses.mak.tags \ make-variable-on-cmdline.mak.tags masm.asm.tags \ matlab_backtracking.m.tags matlab_test.m.tags maze.erl.tags \ members.f90.tags misc_types.f90.tags misc_types.f.tags \ mode.php.tags moniker.x68.asm.tags namelist.f.tags \ namespace.cpp.tags namespaces2.php.tags namespaces.php.tags \ no_terminator.js.tags non-ascii-ident1.php.tags \ numlib.f90.tags objectivec_implementation.mm.tags \ objectivec_interface.mm.tags objectivec_property.mm.tags \ objectivec_protocol.mm.tags Package.pm.tags \ php5_5_class_kw.php.tags parenthesis-rvalue.js.tags \ preprocessor.f90.tags procedure_pointer_module.f90.tags \ procpoint.f90.tags property.cs.tags prototype.h.tags \ pure_elem.f95.tags py_constructor_arglist.py.tags \ py-skipped-string.py.tags \ python-anonymous-nestlevel_ctags-bug-356.py.tags \ python-comments.py.tags qualified_types.f90.tags \ random.sql.tags readlob.sql.tags readlong.sql.tags \ recursive.f95.tags refcurs.sql.tags regexp.js.tags \ return-hint.zep.tags return-types.go.tags \ ruby-block-call.rb.tags ruby-doc.rb.tags \ ruby-namespaced-class.rb.tags \ ruby-scope-after-anonymous-class.rb.tags \ ruby-sf-bug-364.rb.tags rules.t2t.tags sample.t2t.tags \ secondary_fcn_name.js.tags semicolon.f90.tags shebang.js.tags \ signature.cpp.tags simple.abc.tags simple.asciidoc.tags \ simple.au3.tags simple.bas.tags simple.bat.tags \ simple.clj.tags simple.conf.tags simple.d.tags \ simple.diff.tags simple.docbook.tags simple.hs.tags \ simple.hx.tags simple.html.tags simple.inp.tags simple.js.tags \ simple.json.tags simple.ksh.tags simple.lisp.tags \ simple.lua.tags simple.mak.tags simple.md.tags simple.php.tags \ simple.pl.tags simple.ps1.tags simple.py.tags simple.rb.tags \ simple.rst.tags simple.sh.tags simple.tcl.tags simple.ts.tags \ simple.vala.tags simple.zep.tags size_t_wchar_t_alias.d.tags \ size_t_wchar_t_typedef.c.tags spurious_label_tags.c.tags \ sql_single_quote.sql.tags square_parens.f90.tags \ state_machine.v.tags static_array.c.tags stdcall.f.tags \ strings.php.tags strings.rb.tags structure.f.tags \ tabindent.py.tags test.erl.tags test.go.tags test.py.tags \ test_input.rs.tags test_input2.rs.tags titles.t2t.tags \ traffic_signal.v.tags traits.php.tags ui5.controller.js.tags \ union.f.tags value.f.tags var-and-return-type.cpp.tags \ vhdl-component.vhd.tags vhdl-local.vhd.tags vhdl-port.vhd.tags \ vhdl-process.vhd.tags vhdl-type.vhd.tags whitespaces.php.tags \ $(am__EXEEXT_1) am__EXEEXT_3 = $(am__EXEEXT_2) TEST_SUITE_LOG = test-suite.log am__test_logs1 = $(TESTS:=.log) am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) TEST_LOGS = $(am__test_logs2:.tags.log=.log) TAGS_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver TAGS_LOG_COMPILE = $(TAGS_LOG_COMPILER) $(AM_TAGS_LOG_FLAGS) \ $(TAGS_LOG_FLAGS) am__set_b = \ case '$@' in \ */*) \ case '$*' in \ */*) b='$*';; \ *) b=`echo '$@' | sed 's/\.log$$//'`; \ esac;; \ *) \ b='$*';; \ esac am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/test-driver DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) pkgdatadir = @pkgdatadir@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DEPENDENCIES = @DEPENDENCIES@ DLLTOOL = @DLLTOOL@ DOXYGEN = @DOXYGEN@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GEANY_DATA_DIR = @GEANY_DATA_DIR@ GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ GMSGFMT = @GMSGFMT@ GMSGFMT_015 = @GMSGFMT_015@ GREP = @GREP@ GTK_CFLAGS = @GTK_CFLAGS@ GTK_LIBS = @GTK_LIBS@ GTK_VERSION = @GTK_VERSION@ HAVE_CXX17 = @HAVE_CXX17@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTLLIBS = @INTLLIBS@ INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBGEANY_CFLAGS = @LIBGEANY_CFLAGS@ LIBGEANY_EXPORT_CFLAGS = @LIBGEANY_EXPORT_CFLAGS@ LIBGEANY_LDFLAGS = @LIBGEANY_LDFLAGS@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBICONV = @LTLIBICONV@ LTLIBINTL = @LTLIBINTL@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAC_INTEGRATION_CFLAGS = @MAC_INTEGRATION_CFLAGS@ MAC_INTEGRATION_LIBS = @MAC_INTEGRATION_LIBS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POSUB = @POSUB@ PYTHON = @PYTHON@ PYTHON_COMMAND = @PYTHON_COMMAND@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RST2HTML = @RST2HTML@ RST2PDF = @RST2PDF@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SORT = @SORT@ STRIP = @STRIP@ UNIQ = @UNIQ@ USE_NLS = @USE_NLS@ VERSION = @VERSION@ XGETTEXT = @XGETTEXT@ XGETTEXT_015 = @XGETTEXT_015@ XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ dist_check_SCRIPTS = runner.sh NULL = test_sources = \ 1795612.js \ 1850914.js \ 1878155.js \ 1880687.js \ 2023624.js \ 3184782.sql \ 3470609.js \ 3526726.tex \ 68hc11.asm \ actionscript/as-first-token.as \ actionscript/classes.as \ actionscript/const2.as \ actionscript/const.as \ actionscript/method-attributes.as \ actionscript/packages.as \ actionscript/sampler.as \ ada-adb.adb \ ada-ads.ads \ ada-expression-function.adb \ ada-expression-function-generic.adb \ ada-overriding.ads \ ada-package-generic.ads \ ada-task.adb \ angle_bracket.cpp \ anonymous_functions.php \ arraylist.js \ array_ref_and_out.cs \ array_spec.f90 \ array-spec.f90 \ attributes.cs \ auto.f \ backslashes.c \ bit_field.c \ block.f90 \ bracematch.js \ bug1020715.cpp \ bug1020715.c \ bug1086609.c \ bug1093123.cpp \ bug1111214-j-chan.v \ bug1111214.v \ bug1201689.c \ bug1447756.java \ bug1458930.c \ bug1466117.c \ bug1491666.c \ bug1515910.cs \ bug1548443.cpp \ bug1563476.cpp \ bug1570779.sql \ bug1575055.cpp \ bug1585745.cpp \ bug1611054.cs \ bug1691412.java \ bug1742588.rb \ bug1743330.v \ bug1764143.h \ bug1764148.py \ bug1770479.cpp \ bug1773926.cpp \ bug1777344.java \ bug1799340.cpp \ bug1799343-1.cpp \ bug1799343-2.cpp \ bug1800065.cs \ bug1809024.py \ bug1830343.cs \ bug1830344.cs \ bug1856363.py \ bug1906062.py \ bug1907083.cpp \ bug1924919.cpp \ bug1938565.sql \ bug1944150.sql \ bug1950327.js \ bug1988026.py \ bug1988027.py \ bug1988130.py \ bug2049723.java \ bug2075402.py \ bug2117073.java \ bug2374109.vhd \ bug2411878.cs \ bug2747828.v \ bug2777310.js \ bug2781264.rb \ bug2886870.tex \ bug2888482.js \ bug3036476.js \ bug3168705.py \ bug3571233.js \ bug507864.c \ bug538629.asm \ bug556645.c \ bug556646.c \ bug565813.f90 \ bug612019.pas \ bug612621.pl \ bug620288.f \ bug639639.h \ bug639644.hpp \ bug665086.cpp \ bug670433.f90 \ bug699171.py \ bug722501.sql \ bug726712.f90 \ bug726875.f90 \ bug734933.f90 \ bug762027.v \ bug814263.java \ bug823000.sql \ bug842077.pl \ bug849591.cpp \ bug852368.cpp \ bug858165.f90 \ bug872494.cpp \ bug877956.f90 \ bug960316.v \ bug961001.v \ byte.f \ c-digraphs.c \ c-trigraphs.c \ case_sensitivity.php \ char-selector.f90 \ classes.php \ cobol/helloworld.cbl \ cobol/helloworld2.cbl \ cobol/levels.cbl \ cobol/quoted-program-id.cbl \ cobol/simple.cbl \ common.f \ complex-return.js \ continuation.f90 \ continuation.mak \ countall.sql \ cpp_destructor.cpp \ css-at-rules.css \ css-at-supports.css \ css-attribute-selectors.css \ css-comma-no-space.css \ css-namespace-selectors.css \ css-pseudo-classes.css \ css-simple.css \ css-singlequote-in-comment-issue2.css \ css-tag-types.css \ css-trivial.css \ cython_sample.pyx \ cython_sample2.pyx \ cxx11enum.cpp \ cxx11-final.cpp \ cxx11-noexcept.cpp \ cxx11-override.cpp \ cxx11-raw-strings.cpp \ cxx14-combined.cpp \ db-trig.sql \ debian_432872.f90 \ directives.c \ dopbl2.f \ dotted-names.json \ enum.c \ enum.f90 \ enum.java \ enumerators.f90 \ events.cs \ extern_variable.h \ forall_module.f90 \ format.pl \ fortran_associate.f90 \ fortran_line_continuation.f90 \ func_typedef.h \ gdscript-inner-class.gd \ gdscript-modifiers.gd \ gdscript-no-implicit-class.gd \ geany.nsi \ general.cs \ hex2dec.sql \ implied_program.f \ indexer.cs \ infinite_loop.java \ ingres_procedures.sql \ initialization.f90 \ interface_indexers.cs \ interface_properties.cs \ interfaces.f90 \ internal.cs \ intro_orig.tex \ intro.tex \ invalid_name.f90 \ java_enum.java \ js-broken-strings.js \ js-class-related-unterminated.js \ js-const.js \ js-implicit-semicolons.js \ js-let.js \ js-scope.js \ js-signature.js \ js-string-continuation.js \ js-sub-block-scope.js \ js-unknown-construct-nesting.js \ julia-corner_cases.jl \ jsFunc_tutorial.js \ keyword_abstract.cs \ keyword_catch_try.cs \ keyword_class.cs \ keyword_const.cs \ keyword_delegate.cs \ keyword_enum.cs \ keyword_event.cs \ keyword_explicit.cs \ keyword_extern.cs \ keyword_implicit.cs \ keyword_interface.cs \ keyword_namespace.cs \ keyword_names.f90 \ keyword_out.cs \ keyword_override.cs \ keyword_params.cs \ keyword_private.cs \ keyword_protected.cs \ keyword_public.cs \ keyword_sealed.cs \ keyword_static.cs \ keyword_struct.cs \ keyword_virtual.cs \ keyword_volatile.cs \ labels.sql \ lanus.for \ line_directives.c \ local.c \ macros.c \ make-comment-in-rule.mak \ make-gnumake-pattern-rules.mak \ make-multi-target.mak \ make-parentheses.mak \ make-target-with-parentheses.mak \ make-variable-on-cmdline.mak \ masm.asm \ matlab_backtracking.m \ matlab_test.m \ maze.erl \ members.f90 \ misc_types.f90 \ misc_types.f \ mode.php \ moniker.x68.asm \ namelist.f \ namespace.cpp \ namespaces2.php \ namespaces.php \ no_terminator.js \ non-ascii-ident1.php \ numlib.f90 \ objectivec_implementation.mm \ objectivec_interface.mm \ objectivec_property.mm \ objectivec_protocol.mm \ Package.pm \ php5_5_class_kw.php \ parenthesis-rvalue.js \ preprocessor.f90 \ procedure_pointer_module.f90 \ procpoint.f90 \ property.cs \ prototype.h \ pure_elem.f95 \ py_constructor_arglist.py \ py-skipped-string.py \ python-anonymous-nestlevel_ctags-bug-356.py \ python-comments.py \ qualified_types.f90 \ random.sql \ readlob.sql \ readlong.sql \ recursive.f95 \ refcurs.sql \ regexp.js \ return-hint.zep \ return-types.go \ ruby-block-call.rb \ ruby-doc.rb \ ruby-namespaced-class.rb \ ruby-scope-after-anonymous-class.rb \ ruby-sf-bug-364.rb \ rules.t2t \ sample.t2t \ secondary_fcn_name.js \ semicolon.f90 \ shebang.js \ signature.cpp \ simple.abc \ simple.asciidoc \ simple.au3 \ simple.bas \ simple.bat \ simple.clj \ simple.conf \ simple.d \ simple.diff \ simple.docbook \ simple.hs \ simple.hx \ simple.html \ simple.inp \ simple.js \ simple.json \ simple.ksh \ simple.lisp \ simple.lua \ simple.mak \ simple.md \ simple.php \ simple.pl \ simple.ps1 \ simple.py \ simple.rb \ simple.rst \ simple.sh \ simple.tcl \ simple.ts \ simple.vala \ simple.zep \ size_t_wchar_t_alias.d \ size_t_wchar_t_typedef.c \ spurious_label_tags.c \ sql_single_quote.sql \ square_parens.f90 \ state_machine.v \ static_array.c \ stdcall.f \ strings.php \ strings.rb \ structure.f \ tabindent.py \ test.erl \ test.go \ test.py \ test_input.rs \ test_input2.rs \ titles.t2t \ traffic_signal.v \ traits.php \ ui5.controller.js \ union.f \ value.f \ var-and-return-type.cpp \ vhdl-component.vhd \ vhdl-local.vhd \ vhdl-port.vhd \ vhdl-process.vhd \ vhdl-type.vhd \ whitespaces.php \ $(NULL) test_results = $(test_sources:=.tags) TEST_EXTENSIONS = .tags TAGS_LOG_COMPILER = $(srcdir)/runner.sh AM_TAGS_LOG_FLAGS = $(top_builddir)/src/geany$(EXEEXT) AM_TESTS_ENVIRONMENT = top_srcdir=$(top_srcdir) top_builddir=$(top_builddir) EXTRA_DIST = $(test_sources) $(test_results) \ $(check_processing_order_sources) # check processing order of files on the command line check_processing_order_sources = \ process_order.c.tags process_order_1.h process_order_2.h all: all-am .SUFFIXES: .SUFFIXES: .log .tags .tags$(EXEEXT) .trs $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tests/ctags/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu tests/ctags/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags TAGS: ctags CTAGS: cscope cscopelist: # Recover from deleted '.trs' file; this should ensure that # "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create # both 'foo.log' and 'foo.trs'. Break the recipe in two subshells # to avoid problems with "make -n". .log.trs: rm -f $< $@ $(MAKE) $(AM_MAKEFLAGS) $< # Leading 'am--fnord' is there to ensure the list of targets does not # expand to empty, as could happen e.g. with make check TESTS=''. am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) am--force-recheck: @: $(TEST_SUITE_LOG): $(TEST_LOGS) @$(am__set_TESTS_bases); \ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ redo_bases=`for i in $$bases; do \ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ done`; \ if test -n "$$redo_bases"; then \ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ if $(am__make_dryrun); then :; else \ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ fi; \ fi; \ if test -n "$$am__remaking_logs"; then \ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ "recursion detected" >&2; \ elif test -n "$$redo_logs"; then \ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ fi; \ if $(am__make_dryrun); then :; else \ st=0; \ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ for i in $$redo_bases; do \ test -f $$i.trs && test -r $$i.trs \ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ test -f $$i.log && test -r $$i.log \ || { echo "$$errmsg $$i.log" >&2; st=1; }; \ done; \ test $$st -eq 0 || exit 1; \ fi @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ ws='[ ]'; \ results=`for b in $$bases; do echo $$b.trs; done`; \ test -n "$$results" || results=/dev/null; \ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ if test `expr $$fail + $$xpass + $$error` -eq 0; then \ success=true; \ else \ success=false; \ fi; \ br='==================='; br=$$br$$br$$br$$br; \ result_count () \ { \ if test x"$$1" = x"--maybe-color"; then \ maybe_colorize=yes; \ elif test x"$$1" = x"--no-color"; then \ maybe_colorize=no; \ else \ echo "$@: invalid 'result_count' usage" >&2; exit 4; \ fi; \ shift; \ desc=$$1 count=$$2; \ if test $$maybe_colorize = yes && test $$count -gt 0; then \ color_start=$$3 color_end=$$std; \ else \ color_start= color_end=; \ fi; \ echo "$${color_start}# $$desc $$count$${color_end}"; \ }; \ create_testsuite_report () \ { \ result_count $$1 "TOTAL:" $$all "$$brg"; \ result_count $$1 "PASS: " $$pass "$$grn"; \ result_count $$1 "SKIP: " $$skip "$$blu"; \ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ result_count $$1 "FAIL: " $$fail "$$red"; \ result_count $$1 "XPASS:" $$xpass "$$red"; \ result_count $$1 "ERROR:" $$error "$$mgn"; \ }; \ { \ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ $(am__rst_title); \ create_testsuite_report --no-color; \ echo; \ echo ".. contents:: :depth: 2"; \ echo; \ for b in $$bases; do echo $$b; done \ | $(am__create_global_log); \ } >$(TEST_SUITE_LOG).tmp || exit 1; \ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ if $$success; then \ col="$$grn"; \ else \ col="$$red"; \ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ fi; \ echo "$${col}$$br$${std}"; \ echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \ echo "$${col}$$br$${std}"; \ create_testsuite_report --maybe-color; \ echo "$$col$$br$$std"; \ if $$success; then :; else \ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ if test -n "$(PACKAGE_BUGREPORT)"; then \ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ fi; \ echo "$$col$$br$$std"; \ fi; \ $$success || exit 1 check-TESTS: $(dist_check_SCRIPTS) @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ log_list=`for i in $$bases; do echo $$i.log; done`; \ trs_list=`for i in $$bases; do echo $$i.trs; done`; \ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ exit $$?; recheck: all $(dist_check_SCRIPTS) @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ bases=`for i in $$bases; do echo $$i; done \ | $(am__list_recheck_tests)` || exit 1; \ log_list=`for i in $$bases; do echo $$i.log; done`; \ log_list=`echo $$log_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ am__force_recheck=am--force-recheck \ TEST_LOGS="$$log_list"; \ exit $$? .tags.log: @p='$<'; \ $(am__set_b); \ $(am__check_pre) $(TAGS_LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_TAGS_LOG_DRIVER_FLAGS) $(TAGS_LOG_DRIVER_FLAGS) -- $(TAGS_LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) @am__EXEEXT_TRUE@.tags$(EXEEXT).log: @am__EXEEXT_TRUE@ @p='$<'; \ @am__EXEEXT_TRUE@ $(am__set_b); \ @am__EXEEXT_TRUE@ $(am__check_pre) $(TAGS_LOG_DRIVER) --test-name "$$f" \ @am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ @am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TAGS_LOG_DRIVER_FLAGS) $(TAGS_LOG_DRIVER_FLAGS) -- $(TAGS_LOG_COMPILE) \ @am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) $(dist_check_SCRIPTS) $(MAKE) $(AM_MAKEFLAGS) check-TESTS check-local check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: check-am install-am install-strip .PHONY: all all-am check check-TESTS check-am check-local clean \ clean-generic clean-libtool cscopelist-am ctags-am distclean \ distclean-generic distclean-libtool distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am recheck tags-am \ uninstall uninstall-am .PRECIOUS: Makefile .PHONY: check-processing-order check-processing-order: $(check_processing_order_sources) $(AM_TESTS_ENVIRONMENT) \ $(srcdir)/runner.sh $(top_builddir)/src/geany$(EXEEXT) --result $(check_processing_order_sources:%=$(srcdir)/%) check-local: check-processing-order # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: geany-2.0/tests/ctags/3470609.js0000644000175000017500000000151014514252267013041 00000000000000/* * Test for properties values. Everything is valid here and must be * correctly parsed. * * Output of ctags -f - 3470609.js should be: * * Properties: * root.array * root.decimal * root.id * root.neg * root.parentheses * root.string * root.subObject.subProperty * * Classes: * root * root.subObject * * Methods: * root.method * root.subObject.subFunction * * Functions: * f */ var root = { 'string' : 'hello world', 'method' : function() { x = 42; }, 'id' : 1, 'neg' : -1, 'decimal' : 1.3, 'subObject' : { 'subProperty': 42, 'subFunction': function() { y = 43; } }, 'array' : [1, 2, 3], 'parentheses' : (2 * (2 + 3)) } function f() { } geany-2.0/tests/ctags/keyword_sealed.cs0000644000175000017500000000046414514252267015206 00000000000000// cs_sealed_keyword.cs // Sealed classes using System; sealed class MyClass { public int x; public int y; } class MainClass { public static void Main() { MyClass mC = new MyClass(); mC.x = 110; mC.y = 150; Console.WriteLine("x = {0}, y = {1}", mC.x, mC.y); } } geany-2.0/tests/ctags/ada-ads.ads.tags0000644000175000017500000000145014514252267014572 00000000000000AdjustÌ1024ÎGenStackÖ0 prototype: GenStack :: Adjust DataÌ64ÎNodeÖ0 member: Node :: Data Data_PtrÌ4096ÎGenStackÖ0 typedef: GenStack :: Data_Ptr EmptyÌ1024ÎGenStackÖ0 prototype: GenStack :: Empty FinalizeÌ1024ÎGenStackÖ0 prototype: GenStack :: Finalize GenStackÌ512Ö0 package: GenStack HeadÌ64ÎStackÖ0 member: Stack :: Head InitializeÌ1024ÎGenStackÖ0 prototype: GenStack :: Initialize NextÌ64ÎNodeÖ0 member: Node :: Next NodeÌ4096ÎGenStackÖ0 typedef: GenStack :: Node Node_PtrÌ4096ÎGenStackÖ0 typedef: GenStack :: Node_Ptr PopÌ1024ÎGenStackÖ0 prototype: GenStack :: Pop PushÌ1024ÎGenStackÖ0 prototype: GenStack :: Push StackÌ4096ÎGenStackÖ0 typedef: GenStack :: Stack StackDataÌ4096ÎGenStackÖ0 typedef: GenStack :: StackData TopÌ1024ÎGenStackÖ0 prototype: GenStack :: Top geany-2.0/tests/ctags/test.py0000644000175000017500000000017014514252267013201 00000000000000#!/usr/bin/env python def main(): return 0 if __name__ == '__main__': main() var = 'hi' var2 = 'hi' # blah = blah geany-2.0/tests/ctags/simple.ts.tags0000644000175000017500000001203514514252267014451 00000000000000AÌ1Ö0 class: A AÌ4ÎTestÖ0 enumerator: Test :: A ArrayÌ32Ö0 interface: Array BÌ4ÎTestÖ0 enumerator: Test :: B BankAccountÌ1Ö0 class: BankAccount BlueÌ4ÎColorÖ0 enumerator: Color :: Blue BoldÌ4ÎStyleÖ0 enumerator: Style :: Bold CÌ1Ö0 class: C CÌ4ÎTestÖ0 enumerator: Test :: C CPointÌ1Ö0 class: CPoint CheckingAccountÌ1Ö0 class: CheckingAccount ColorÌ2Ö0 enum: Color ComparisonÌ2Ö0 enum: Comparison CompilerOptionsÌ32Ö0 interface: CompilerOptions DÌ1Ö0 class: D DÌ4ÎTestÖ0 enumerator: Test :: D DocumentÌ32Ö0 interface: Document EÌ4ÎTestÖ0 enumerator: Test :: E EmphasisÌ4ÎStyleÖ0 enumerator: Style :: Emphasis EqualToÌ4ÎComparisonÖ0 enumerator: Comparison :: EqualTo GreaterThanÌ4ÎComparisonÖ0 enumerator: Comparison :: GreaterThan GreenÌ4ÎColorÖ0 enumerator: Color :: Green HyperlinkÌ4ÎStyleÖ0 enumerator: Style :: Hyperlink ItalicÌ4ÎStyleÖ0 enumerator: Style :: Italic JQueryÌ32Ö0 interface: JQuery JQueryStaticÌ32Ö0 interface: JQueryStatic LessThanÌ4ÎComparisonÖ0 enumerator: Comparison :: LessThan LettersOnlyValidatorÌ1ÎValidationÖ0 class: Validation :: LettersOnlyValidator ListÌ1Ö0 class: List ListÌ32Ö0 interface: List MessengerÌ1Ö0 class: Messenger MoverÌ32Ö0 interface: Mover MoverShakerÌ32Ö0 interface: MoverShaker NoneÌ4ÎStyleÖ0 enumerator: Style :: None PointÌ1Ö0 class: Point RedÌ4ÎColorÖ0 enumerator: Color :: Red ShakerÌ32Ö0 interface: Shaker SimpleRecordÌ32Ö0 interface: SimpleRecord StringValidatorÌ32ÎValidationÖ0 interface: Validation :: StringValidator StyleÌ2Ö0 enum: Style TestÌ2Ö0 enum: Test UnderlineÌ4ÎStyleÖ0 enumerator: Style :: Underline ValidationÌ256Ö0 namespace: Validation ZipCodeValidatorÌ1ÎValidationÖ0 class: Validation :: ZipCodeValidator addÌ16Ö0 function: add balanceÌ64ÎBankAccountÖ0 member: BankAccount :: balance closureÌ128ÎAÖ0 method: A :: closure constructorÌ128ÎCPointÖ0 method: CPoint :: constructor constructorÌ128ÎCheckingAccountÖ0 method: CheckingAccount :: constructor constructorÌ128ÎListÖ0 method: List :: constructor constructorÌ128ÎPointÖ0 method: Point :: constructor createElementÌ128ÎDocumentÖ0 method: Document :: createElement dataÌ64ÎDÖ0 member: D :: data dataÌ64ÎListÖ0 member: List :: data depositÌ128ÎBankAccountÖ0 method: BankAccount :: deposit fÌ128ÎAÖ0 method: A :: f fakePointBuilderÌ64ÎPointÖ0 member: Point :: fakePointBuilder funÌ64ÎAÖ0 member: A :: fun getÌ128ÎJQueryStaticÖ0 method: JQueryStatic :: get getDataÌ128ÎDÖ0 method: D :: getData getSomethingÌ128ÎMoverShakerÖ0 method: MoverShaker :: getSomething getSomethingSophisticatedÌ128ÎMoverShakerÖ0 method: MoverShaker :: getSomethingSophisticated getStatusÌ128ÎMoverÖ0 method: Mover :: getStatus getStatusÌ128ÎMoverShakerÖ0 method: MoverShaker :: getStatus getStatusÌ128ÎShakerÖ0 method: Shaker :: getStatus getTplÌ128ÎMoverShakerÖ0 method: MoverShaker :: getTpl getXAsTÌ128ÎAÖ0 method: A :: getXAsT insertAfterÌ128ÎListÖ0 method: List :: insertAfter isAcceptableÌ128ÎValidation.LettersOnlyValidatorÖ0 method: Validation.LettersOnlyValidator :: isAcceptable isAcceptableÌ128ÎValidation.StringValidatorÖ0 method: Validation.StringValidator :: isAcceptable isAcceptableÌ128ÎValidation.ZipCodeValidatorÖ0 method: Validation.ZipCodeValidator :: isAcceptable itemÌ64ÎListÖ0 member: List :: item lengthÌ64ÎArrayÖ0 member: Array :: length lengthÌ128ÎPointÖ0 method: Point :: length lettersRegexpÌ65536ÎValidationÖ0 macro: Validation :: lettersRegexp logÌ128ÎListÖ0 method: List :: log longArgsFunÌ128ÎAÖ0 method: A :: longArgsFun messageÌ64ÎMessengerÖ0 member: Messenger :: message moveÌ128ÎMoverÖ0 method: Mover :: move nameÌ16384Ö0 variable: name nextÌ64ÎListÖ0 member: List :: next normalizedPathÌ65536ÎA.closureÖ0 macro: A.closure :: normalizedPath numberRegexpÌ65536ÎValidationÖ0 macro: Validation :: numberRegexp originÌ64ÎPointÖ0 member: Point :: origin ownerÌ64ÎListÖ0 member: List :: owner propertyAÌ64ÎSimpleRecordÖ0 member: SimpleRecord :: propertyA propertyBÌ64ÎSimpleRecordÖ0 member: SimpleRecord :: propertyB propertyCÌ64ÎSimpleRecordÖ0 member: SimpleRecord :: propertyC registerÌ128ÎAÖ0 method: A :: register sÌ16384Ö0 variable: s shakeÌ128ÎShakerÖ0 method: Shaker :: shake sourcePathÌ64ÎCompilerOptionsÖ0 member: CompilerOptions :: sourcePath startÌ128ÎMessengerÖ0 method: Messenger :: start strictÌ64ÎCompilerOptionsÖ0 member: CompilerOptions :: strict stringsÌ16384Ö0 variable: strings targetPathÌ64ÎCompilerOptionsÖ0 member: CompilerOptions :: targetPath textÌ128ÎJQueryÖ0 method: JQuery :: text validatorsÌ16384Ö0 variable: validators withoutTypeÌ64ÎSimpleRecordÖ0 member: SimpleRecord :: withoutType writeCheckÌ128ÎCheckingAccountÖ0 method: CheckingAccount :: writeCheck xÌ64ÎAÖ0 member: A :: x xÌ64ÎCÖ0 member: C :: x xÌ64ÎCPointÖ0 member: CPoint :: x xÌ64ÎPointÖ0 member: Point :: x yÌ64ÎAÖ0 member: A :: y yÌ64ÎCPointÖ0 member: CPoint :: y yÌ64ÎPointÖ0 member: Point :: y geany-2.0/tests/ctags/general.cs0000644000175000017500000000114514514252267013617 00000000000000// General Structure of a C# Program // A skeleton of a C# program using System; namespace MyNamespace1 { class MyClass1 { } struct MyStruct { } interface IMyInterface { } delegate int MyDelegate(); enum MyEnum { } namespace MyNamespace2 { } class MyClass2 { public static void Main(string[] args) { } } } // Using Fully Qualified Names namespace N1 // N1 { class C1 // N1.C1 { class C2 // N1.C1.C2 { } } namespace N2 // N1.N2 { class C2 // N1.N2.C2 { } } } geany-2.0/tests/ctags/bug2049723.java0000644000175000017500000000020714514252267014044 00000000000000import javax.annotation.Nonnull; public class bug2049723 { public void m1(String arg) {} public void m2(@Nonnull String arg) {} } geany-2.0/tests/ctags/simple.hs.tags0000644000175000017500000000034014514252267014431 00000000000000BoolÌ4096Ö0 typedef: Bool CardsÌ256Ö0 namespace: Cards FalseÌ65536Ö0 macro: False FdÌ4096Ö0 typedef: Fd FdÌ65536Ö0 macro: Fd IntÌ4096Ö0 typedef: Int TrueÌ65536Ö0 macro: True addÌ16Ö0 function: add geany-2.0/tests/ctags/keyword_event.cs.tags0000644000175000017500000000301314514252267016020 00000000000000ExplicitEventsSampleÌ1Ö0 class: ExplicitEventsSample FireAwayÌ128Í()ÎIÖ0Ïvoid method: void I :: FireAway() FireAwayÌ128Í()ÎMyClassÖ0Ïpublic void method: public void MyClass :: FireAway() FireEventsÌ128Í()ÎExplicitEventsSampleÖ0Ïprivate void method: private void ExplicitEventsSample :: FireEvents() IÌ32Ö0 interface: I I1Ì32Ö0 interface: I1 I2Ì32Ö0 interface: I2 MainÌ128Í()ÎMainClassÖ0Ïpublic void method: public void MainClass :: Main() MainÌ128Í()ÎMyClassÖ0Ïpublic void method: public void MyClass :: Main() MainClassÌ1Ö0 class: MainClass MyClassÌ1Ö0 class: MyClass MyDelegateÌ128Í()Ö0Ïpublic delegate void method: public delegate void MyDelegate() MyDelegate1Ì128Í(int i)Ö0Ïpublic delegate void method: public delegate void MyDelegate1(int i) MyDelegate1Ì128Í()Ö0Ïpublic delegate void method: public delegate void MyDelegate1() MyDelegate2Ì128Í(string s)Ö0Ïpublic delegate int method: public delegate int MyDelegate2(string s) MyDelegate3Ì128Í(int i, object o)Ö0Ïpublic delegate void method: public delegate void MyDelegate3(int i, object o) MyDelegate4Ì128Í()Ö0Ïpublic delegate void method: public delegate void MyDelegate4() MyEvent2StorageÌ8ÎExplicitEventsSampleÖ0ÏMyDelegate2 field: MyDelegate2 ExplicitEventsSample :: MyEvent2Storage PropertyEventsSampleÌ1Ö0 class: PropertyEventsSample eventTableÌ8ÎPropertyEventsSampleÖ0ÏHashtable field: Hashtable PropertyEventsSample :: eventTable fÌ128Í()ÎMainClassÖ0Ïprivate void method: private void MainClass :: f() geany-2.0/tests/ctags/sql_single_quote.sql0000644000175000017500000000035614514252267015754 00000000000000CREATE PROCEDURE "p1"( ) BEGIN SET someting = ChannelPath + '\' + ChannelName; END; CREATE PROCEDURE "p2"( ) BEGIN SET someting = '''' + ChannelPath + ''''; END; CREATE PROCEDURE "p3"( ) BEGIN END; geany-2.0/tests/ctags/ada-expression-function.adb0000644000175000017500000000157414514252267017076 00000000000000with Ada.Text_IO; procedure Test is My_Type : Boolean := True; procedure Tagged_Procedure is function Boolean_As_String return String is (case My_Type is when True => "True Value", when False => "False Value"); function Another_Boolean_As_String return String is (case My_Type is when True => "; function dummy0 return String is (", when False => "; function dummy1 return String is ("); procedure p0 is begin Ada.Text_IO.put ("-0"); end p0; function Yet_Boolean_As_String return String is (case My_Type is when True => "1", when False => "0"); procedure p1 is begin Ada.Text_IO.put ("-1"); end p1; begin null; end Tagged_Procedure; procedure Not_Tagged_Procedure is begin null; end Not_Tagged_Procedure; begin null; end Test; geany-2.0/tests/ctags/macros.c.tags0000644000175000017500000000043614514252267014242 00000000000000FUNCTION_LIKEÌ131072Í(a,b)Ö0 macro_arg: FUNCTION_LIKE(a,b) MACROÌ1024Í(foo)Ö0 prototype: MACRO(foo) VARIABLE_LIKEÌ65536Ö0 macro: VARIABLE_LIKE WeakSymbolÌ65536Ö0 macro: WeakSymbol prototypeÌ1024Í(int arg1,void * arg2)Ö0Ïvoid prototype: void prototype(int arg1,void * arg2) geany-2.0/tests/ctags/moniker.x68.asm0000644000175000017500000001155614514252267014454 00000000000000* http://www.xrmx.com/solutions/software/68k-fe/samples/moniker.x68 * MONIKER.X68 * Author : Greg Colley * Date : 29/01/99 * Program Description. * This will prompt for surname and firstname, and check if its uppercase * If it is it prints Initial + surname else it repromts. * This program will only exit when nothing is entered in the surname or * firstname. PRTSTR EQU 1 Print string Function READSTR EQU 2 Read string function ORG $1000 Start of code location * Print user prompt for enter the firstname * ========================================= START MOVEA.L #PROMPT1,A1 Pointer to start of prompt text MOVE.B #PRTSTR,D0 Set up print string function MOVE.W #(PROMPT2-PROMPT1),D1 The prompt string length TRAP #15 Print Prompt * Get firstname * ============= MOVEA.L #F_NAME,A1 Pointer to store the sentence MOVE.B #READSTR,D0 Set up readstring function TRAP #15 Get string from KB MOVE.W D1,D4 Save length of input string to d4 * Check if Return is pressed CMPI.W #0,D4 Is the length = 0 BEQ QUIT If length = 0 then Quit * Set up the stuff to check it the entered word is in CAPS * ======================================================== MOVEA.L #F_NAME,A0 Move the first char to A0 JSR CHECK2 Check if uppercase CMPI.B #1,D5 See if all the sentence is CAPS BCS START if it is'nt then re-enter * Print user prompt for enter the surname * ======================================= SURNAME MOVEA.L #PROMPT2,A1 Pointer to start of prompt text MOVE.B #PRTSTR,D0 Set up print string function MOVE.W #(F_NAME-PROMPT2),D1 The prompt string length TRAP #15 Print Prompt * Get surname * =========== MOVEA.L #S_NAME,A1 Pointer to store the sentence MOVE.B #READSTR,D0 Set up readstring function TRAP #15 Get string from KB MOVE.W D1,D4 Save length on input string MOVE.W D1,D3 Save length of input string to d3 * Check is Return is pressed CMPI.W #0,D4 Is the length = 0 BEQ QUIT If length = 0 then Quit * Set up the stuff to check it the entered word is in CAPS * ======================================================== MOVEA.L #S_NAME,A0 Move the first char to A0 JSR CHECK2 Check if uppercase CMPI.B #1,D5 See if all the sentence is CAPS BCS SURNAME if it is'nt then re-enter * Move the first char for fname and prints it (Initial Bit) * ========================================================= INITIAL MOVEA.L #F_NAME,A1 Move the first char to A1 MOVE.B (A1),D1 Move the first char of F_NAME to D1 MOVE.B #6,D0 Set up trap number TRAP #15 Print the Initial PRNSURNAME MOVEA.L #S_NAME,A1 Pointer to start of prompt text MOVE.B #0,D0 Set up print string function MOVE.W D3,D1 The prompt string length TRAP #15 Print Prompt QUIT STOP #$2700 Stop the prorgam * Check if uppercase * ================== * This subroutine will return a 1 in, d5 if it's OK or * return a 0 in d5 if its not ok. CHECK2 CMPI.B #'A',(A0) Is Char > A ? BCS RETURNFALSE If no then re-enter CMP.B #('Z'+1),(A0)+ Check if char is < Z BCC RETURNFALSE If it is then it must be a cap SUBI.B #1,D4 Decrease s_name / f_name Length BNE CHECK2 jump if the sentence is not = 0 RETURNTRUE MOVE.B #1,D5 Moves a one to D5 to make CAPS ture RTS Jump back to the main program RETURNFALSE MOVE.B #0,D5 Moves a zero to D5 to make CAPS false RTS Jump back to the main program * Var's & Const's * =============== PROMPT1 DC.B 'Please enter your firstname (Max 80): ' PROMPT2 DC.B 'Please enter your surname (Max 80): ' F_NAME DS.B 80 S_NAME DS.B 80 DUMMY DS.B 1 END $1000 End of assembley geany-2.0/tests/ctags/strings.rb.tags0000644000175000017500000000114614514252267014627 00000000000000AÌ1Ö0 class: A aÌ128Í()ÎAÖ0 method: A :: a() bÌ128Í()ÎAÖ0 method: A :: b() cÌ128Í()ÎA.bÖ0 method: A.b :: c() dÌ128Í()ÎA.b.cÖ0 method: A.b.c :: d() eÌ128Í()ÎA.b.c.dÖ0 method: A.b.c.d :: e() fÌ128Í()ÎA.b.c.dÖ0 method: A.b.c.d :: f() not_me1Ì128Í()ÎA.b.c.dÖ0 method: A.b.c.d :: not_me1() not_me2Ì128Í()ÎA.b.c.dÖ0 method: A.b.c.d :: not_me2() not_me3Ì128Í()ÎA.b.c.dÖ0 method: A.b.c.d :: not_me3() not_me4Ì128Í()ÎA.b.c.dÖ0 method: A.b.c.d :: not_me4() not_me5Ì128Í()ÎA.b.c.dÖ0 method: A.b.c.d :: not_me5() sentinelÌ128Í()ÎA.b.c.d.fÖ0 method: A.b.c.d.f :: sentinel() geany-2.0/tests/ctags/test.go0000644000175000017500000000143414514252267013162 00000000000000package main import "fmt" type ( T1 map[string]int T2 <-chan float32 T3 chan []string T4 chan<- *[12]string T5 interface { Reader() Writer() foo() } ) type T6 struct { _a, _b, _c, _d int int T1 `annotation` *T2 _e float32 //ignored int } const (A = iota;B;C; D = iota << (1 + iota*2) E F=3.14*(1+2*3)/34e7;I=1) type (T7 func (a struct{_ int; _ float32}, b int) (int, map[string]int);T8 float32) var (a, b, c int d T5 e T4 f interface{}) func f1() {};func f2() {};type/*no newline here*/T9 int/*var ignored int const ignored int*/const (G=6); var g int func (t *T1) f3() (a, b int){ return 1, 2 }; var h int func (tt * T7) f4(a func () func ()) (func (), int) {return func (){}, 1};func f5(){};const H=1 func main() { go func (){}() fmt.Println("Hello, 世界") }geany-2.0/tests/ctags/spurious_label_tags.c.tags0000644000175000017500000000011414514252267017015 00000000000000label_forced_tagsÌ16Í(void)Ö0Ïvoid function: void label_forced_tags(void) geany-2.0/tests/ctags/traits.php.tags0000644000175000017500000000050614514252267014627 00000000000000AÌ1Ö0 class: A BÌ1Ö0 class: B __constructÌ16Í()ÎAÖ0 function: A :: __construct() __constructÌ16Í($p)ÎBÖ0 function: B :: __construct($p) stuffÌ16Í($arg1, $arg2)ÎtBarÖ0 function: tBar :: stuff($arg1, $arg2) stuffÌ16Í()ÎtFooÖ0 function: tFoo :: stuff() tBarÌ2048Ö0 struct: tBar tFooÌ2048Ö0 struct: tFoo geany-2.0/tests/ctags/bug1691412.java.tags0000644000175000017500000000042614514252267015001 00000000000000CÌ1Ö0 class: C newInstanceÌ128Í()ÎCÖ0Ï@NonNull @CheckReturnValue public DefaultCipherDialog method: @NonNull @CheckReturnValue public DefaultCipherDialog C :: newInstance() toStringÌ128Í()ÎCÖ0Ï@Override public String method: @Override public String C :: toString() geany-2.0/tests/ctags/namespaces.php0000644000175000017500000000136614514252267014510 00000000000000Tests for namespaces (braced version) Expected output is namespaces: Bar\Baz Foo classes: B [Bar\Baz] C [Foo] functions: __construct [Foo::C] __construct [Bar\Baz::B] a [Foo] a [Bar\Baz] b [Foo] c [Bar\Baz::B] d [Foo::C] inRoot meToo #define ERROR_HAPPENED 50 #define OK 2 #define NEXT_DEFINE 3 int main(int argc, char* argv[]) { printf("Hello world\n"); return 0; } geany-2.0/tests/ctags/bug1907083.cpp.tags0000644000175000017500000000036414514252267014647 00000000000000m1Ì16Í()ÎCÖ0ÏC::T * function: C::T * C :: m1() m2Ì16Í()ÎCÖ0ÏC::T * const function: C::T * const C :: m2() m3Ì16Í()ÎCÖ0ÏC::T const * function: C::T const * C :: m3() m4Ì16Í()ÎCÖ0ÏC::T const * const function: C::T const * const C :: m4() geany-2.0/tests/ctags/bug2886870.tex0000644000175000017500000002163014514252267013742 00000000000000Sample LaTeX file The name of this file is intro.tex. \documentclass[12pt]{article} \usepackage{amsmath} % need for subequations \usepackage{graphicx} % need for figures \usepackage{verbatim} % useful for program listings \usepackage{color} % use if color is used in text \usepackage{subfigure} % use for side-by-side figures \usepackage{hyperref} % use for hypertext links, including those to external documents and URLs % don't need the following. simply use defaults \setlength{\baselineskip}{16.0pt} % 16 pt usual spacing between lines \setlength{\parskip}{3pt plus 2pt} \setlength{\parindent}{20pt} \setlength{\oddsidemargin}{0.5cm} \setlength{\evensidemargin}{0.5cm} \setlength{\marginparsep}{0.75cm} \setlength{\marginparwidth}{2.5cm} \setlength{\marginparpush}{1.0cm} \setlength{\textwidth}{150mm} \begin{comment} \pagestyle{empty} % use if page numbers not wanted \end{comment} % above is the preamble \begin{document} \begin{center} {\large Introduction to \LaTeX} \\ % \\ = new line \copyright 2006 by Harvey Gould \\ December 5, 2006 \end{center} \section{Introduction} \TeX\ looks more difficult than it is. It is almost as easy as $\pi$. See how easy it is to make special symbols such as $\alpha$, $\beta$, $\gamma$, $\delta$, $\sin x$, $\hbar$, $\lambda$, $\ldots$ We also can make subscripts $A_{x}$, $A_{xy}$ and superscripts, $e^x$, $e^{x^2}$, and $e^{a^b}$. We will use \LaTeX, which is based on \TeX\ and has many higher-level commands (macros) for formatting, making tables, etc. More information can be found in Ref.~\cite{latex}. We just made a new paragraph. Extra lines and spaces make no difference. Note that all formulas are enclosed by \$ and occur in \textit{math mode}. The default font is Computer Modern. It includes \textit{italics}, \textbf{boldface}, \textsl{slanted}, and \texttt{monospaced} fonts. \section{Equations} Let us see how easy it is to write equations. \begin{equation} \Delta =\sum_{i=1}^N w_i (x_i - \bar{x})^2 . \end{equation} It is a good idea to number equations, but we can have a equation without a number by writing \begin{equation} P(x) = \frac{x - a}{b - a} , \nonumber \end{equation} and \begin{equation} g = \frac{1}{2} \sqrt{2\pi} . \nonumber \end{equation} We can give an equation a label so that we can refer to it later. \begin{equation} \label{eq:ising} E = -J \sum_{i=1}^N s_i s_{i+1} , \end{equation} Equation~\eqref{eq:ising} expresses the energy of a configuration of spins in the Ising model.\footnote{It is necessary to process (typeset) a file twice to get the counters correct.} We can define our own macros to save typing. For example, suppose that we introduce the macros: \begin{verbatim} \newcommand{\lb}{{\langle}} \newcommand{\rb}{{\rangle}} \end{verbatim} \newcommand{\lb}{{\langle}} \newcommand{\rb}{{\rangle}} Then we can write the average value of $x$ as \begin{verbatim} \begin{equation} \lb x \rb = 3 \end{equation} \end{verbatim} The result is \begin{equation} \lb x \rb = 3 . \end{equation} Examples of more complicated equations: \begin{equation} I = \! \int_{-\infty}^\infty f(x)\,dx \label{eq:fine}. \end{equation} We can do some fine tuning by adding small amounts of horizontal spacing: \begin{verbatim} \, small space \! negative space \end{verbatim} as is done in Eq.~\eqref{eq:fine}. We also can align several equations: \begin{align} a & = b \\ c &= d , \end{align} or number them as subequations: \begin{subequations} \begin{align} a & = b \\ c &= d . \end{align} \end{subequations} We can also have different cases: \begin{equation} \label{eq:mdiv} m(T) = \begin{cases} 0 & \text{$T > T_c$} \\ \bigl(1 - [\sinh 2 \beta J]^{-4} \bigr)^{\! 1/8} & \text{$T < T_c$} \end{cases} \end{equation} write matrices \begin{align} \textbf{T} &= \begin{pmatrix} T_{++} \hfill & T_{+-} \\ T_{-+} & T_{--} \hfill \end{pmatrix} , \nonumber \\ & = \begin{pmatrix} e^{\beta (J + B)} \hfill & e^{-\beta J} \hfill \\ e^{-\beta J} \hfill & e^{\beta (J - B)} \hfill \end{pmatrix}. \end{align} and \newcommand{\rv}{\textbf{r}} \begin{equation} \sum_i \vec A \cdot \vec B = -P\!\int\! \rv \cdot \hat{\mathbf{n}}\, dA = P\!\int \! {\vec \nabla} \cdot \rv\, dV. \end{equation} \section{Tables} Tables are a little more difficult. TeX automatically calculates the width of the columns. \begin{table}[h] \begin{center} \begin{tabular}{|l|l|r|l|} \hline lattice & $d$ & $q$ & $T_{\rm mf}/T_c$ \\ \hline square & 2 & 4 & 1.763 \\ \hline triangular & 2 & 6 & 1.648 \\ \hline diamond & 3 & 4 & 1.479 \\ \hline simple cubic & 3 & 6 & 1.330 \\ \hline bcc & 3 & 8 & 1.260 \\ \hline fcc & 3 & 12 & 1.225 \\ \hline \end{tabular} \caption{\label{tab:5/tc}Comparison of the mean-field predictions for the critical temperature of the Ising model with exact results and the best known estimates for different spatial dimensions $d$ and lattice symmetries.} \end{center} \end{table} \section{Lists} Some example of formatted lists include the following: \begin{enumerate} \item bread \item cheese \end{enumerate} \begin{itemize} \item Tom \item Dick \end{itemize} \section{Figures} We can make figures bigger or smaller by scaling them. Figure~\ref{fig:lj} has been scaled by 60\%. \begin{figure}[h] \begin{center} \includegraphics{figures/sine} \caption{\label{fig:typical}Show me a sine.} \end{center} \end{figure} \begin{figure}[h] \begin{center} \scalebox{0.6}{\includegraphics{figures/lj}} \caption{\label{fig:lj}Plot of the Lennard-Jones potential $u(r)$. The potential is characterized by a length $\sigma$ and an energy $\epsilon$.} \end{center} \end{figure} \section{Literal text} It is desirable to print program code exactly as it is typed in a monospaced font. Use \verb \begin{verbatim} and \verb \end{verbatim} as in the following example: \begin{verbatim} double y0 = 10; // example of declaration and assignment statement double v0 = 0; // initial velocity double t = 0; // time double dt = 0.01; // time step double y = y0; \end{verbatim} The command \verb \verbatiminput{programs/Square.java}\ allows you to list the file \texttt{Square.java} in the directory programs. \section{Special Symbols} \subsection{Common Greek letters} These commands may be used only in math mode. Only the most common letters are included here. $\alpha, \beta, \gamma, \Gamma, \delta,\Delta, \epsilon, \zeta, \eta, \theta, \Theta, \kappa, \lambda, \Lambda, \mu, \nu, \xi, \Xi, \pi, \Pi, \rho, \sigma, \tau, \phi, \Phi, \chi, \psi, \Psi, \omega, \Omega$ \subsubsection{Test for ctags} \subsection{Special symbols} The derivative is defined as \begin{equation} \frac{dy}{dx} = \lim_{\Delta x \to 0} \frac{\Delta y} {\Delta x} \end{equation} \begin{equation} f(x) \to y \quad \mbox{as} \quad x \to x_{0} \end{equation} \begin{equation} f(x) \mathop {\longrightarrow} \limits_{x \to x_0} y \end{equation} \noindent Order of magnitude: \begin{equation} \log_{10}f \simeq n \end{equation} \begin{equation} f(x)\sim 10^{n} \end{equation} Approximate equality: \begin{equation} f(x)\simeq g(x) \end{equation} \LaTeX\ is simple if we keep everything in proportion: \begin{equation} f(x) \propto x^3 . \end{equation} Finally we can skip some space by using commands such as \begin{verbatim} \bigskip \medskip \smallskip \vspace{1pc} \end{verbatim} The space can be negative. \section{\color{red}Use of Color} {\color{blue}{We can change colors for emphasis}}, {\color{green}{but}} {\color{cyan}{who is going pay for the ink?}} \section{\label{morefig}Subfigures} As soon as many students start becoming comfortable using \LaTeX, they want to use some of its advanced features. So we now show how to place two figures side by side. \begin{figure}[h!] \begin{center} \subfigure[Real and imaginary.]{ \includegraphics[scale=0.5]{figures/reim}} \subfigure[Amplitude and phase.]{ \includegraphics[scale=0.5]{figures/phase}} \caption{\label{fig:qm/complexfunctions} Two representations of complex wave functions.} \end{center} \end{figure} We first have to include the necessary package, \verb+\usepackage{subfigure}+, which has to go in the preamble (before \verb+\begin{document}+). It sometimes can be difficult to place a figure in the desired place. Your LaTeX document can be easily modified to make a poster or a screen presentation similar to (and better than) PowerPoint. Conversion to HTML is straightforward. Comments on this tutorial are appreciated. \begin{thebibliography}{5} \bibitem{latex}Helmut Kopka and Patrick W. Daly, \textsl{A Guide to \LaTeX: Document Preparation for Beginners and Advanced Users}, fourth edition, Addison-Wesley (2004). \bibitem{website}Some useful links are given at \url{}. \end{thebibliography} {\small \noindent Updated 5 December 2006.} \end{document} Updated 6 February 2006. geany-2.0/tests/ctags/bug1743330.v.tags0000644000175000017500000000003414514252267014315 00000000000000dummyÌ1Ö0 class: dummy geany-2.0/tests/ctags/bug2777310.js0000644000175000017500000000012614514252267013537 00000000000000var x = 1; var z = {}; var y = []; var a = (42 + 1) * 2; var b = 2 * (42 + 1); geany-2.0/tests/ctags/bug1570779.sql.tags0000644000175000017500000000027114514252267014671 00000000000000addressÌ8ÎemployeesÖ0 field: employees :: address employeesÌ1Ö0 class: employees idÌ8ÎemployeesÖ0 field: employees :: id nameÌ8ÎemployeesÖ0 field: employees :: name geany-2.0/tests/ctags/countall.sql.tags0000644000175000017500000000042014514252267015145 00000000000000row_countÌ16384Ö0 variable: row_count statÌ16384Ö0 variable: stat t_c1_tnameÌ16384Ö0 variable: t_c1_tname t_cidÌ16384Ö0 variable: t_cid t_commandÌ16384Ö0 variable: t_command t_limitÌ16384Ö0 variable: t_limit t_total_recordsÌ16384Ö0 variable: t_total_records geany-2.0/tests/ctags/bug823000.sql.tags0000644000175000017500000000020214514252267014554 00000000000000TESTÌ512Ö0 package: TEST TestFunc1Ì256ÎTESTÖ0 namespace: TEST :: TestFunc1 TestFunc2Ì256ÎTESTÖ0 namespace: TEST :: TestFunc2 geany-2.0/tests/ctags/js-let.js.tags0000644000175000017500000000033014514252267014337 00000000000000aÌ16384Ö0 variable: a bÌ16384Ö0 variable: b funcÌ16Í()Ö0 function: func() groupÌ1Ö0 class: group xÌ64ÎgroupÖ0 member: group :: x yÌ64ÎgroupÖ0 member: group :: y zÌ64ÎgroupÖ0 member: group :: z geany-2.0/tests/ctags/bug1447756.java0000644000175000017500000000034714514252267014060 00000000000000// Java 1.5 generic interfaces appear to be tagged on the // parameterized type name instead of the interface name, // e.g., public interface Foo { public T bar(); } // is tagged on 'T' instead of 'Foo'. geany-2.0/tests/ctags/simple.html0000644000175000017500000000076714514252267014043 00000000000000 geany-2.0/tests/ctags/simple.inp.tags0000644000175000017500000000014014514252267014603 00000000000000AssemblyÌ64Ö0 member: Assembly Part-1Ì1Ö0 class: Part-1 Step-1Ì32Ö0 interface: Step-1 geany-2.0/tests/ctags/simple.js.tags0000644000175000017500000000341514514252267014441 00000000000000DatabaseÌ1Ö0 class: Database ValidClassOneÌ1Í(a,b)Îtestlib.extrasÖ0 class: testlib.extras :: ValidClassOne(a,b) ValidClassTwoÌ1Í()Ö0 class: ValidClassTwo() calculateÌ16Í(number)ÎgetHalfOfÖ0 function: getHalfOf :: calculate(number) executeQueryStringÌ128ÎDatabaseÖ0 method: Database :: executeQueryString getHalfOfÌ16Í(num1, num2, num3)Ö0 function: getHalfOf(num1, num2, num3) getTodaysDateÌ128ÎDatabaseÖ0 method: Database :: getTodaysDate innerThreeÌ16Í(a,b)ÎvalidFunctionThreeÖ0 function: validFunctionThree :: innerThree(a,b) invalidInnerFunctionÌ16Í(a,b)Ö0 function: invalidInnerFunction(a,b) my_global_var1Ì16384Ö0 variable: my_global_var1 my_global_var2Ì16384Ö0 variable: my_global_var2 my_global_var3Ì16384Ö0 variable: my_global_var3 my_global_var4Ì16384Ö0 variable: my_global_var4 onchangeÌ16Í()Îmy_global_var4Ö0 function: my_global_var4 :: onchange() originalvalueÌ16384Ö0 variable: originalvalue validFunctionFiveÌ16Í(a,b)ÎtestlibÖ0 function: testlib :: validFunctionFive(a,b) validFunctionFourÌ16Í(a,b)ÎextraÖ0 function: extra :: validFunctionFour(a,b) validFunctionOneÌ16Í(a,b)Ö0 function: validFunctionOne(a,b) validFunctionSixÌ16Í(a,b)Îtestlib.coreÖ0 function: testlib.core :: validFunctionSix(a,b) validFunctionThreeÌ16Í(a,b)Ö0 function: validFunctionThree(a,b) validFunctionTwoÌ16Í(a,b)Ö0 function: validFunctionTwo(a,b) validMethodFourÌ128Í()ÎValidClassTwoÖ0 method: ValidClassTwo :: validMethodFour() validMethodOneÌ128Í(a,b)Îtestlib.extras.ValidClassOneÖ0 method: testlib.extras.ValidClassOne :: validMethodOne(a,b) validMethodThreeÌ128Í()ÎValidClassTwoÖ0 method: ValidClassTwo :: validMethodThree() validMethodTwoÌ128Í(a,b)Îtestlib.extras.ValidClassOneÖ0 method: testlib.extras.ValidClassOne :: validMethodTwo(a,b) geany-2.0/tests/ctags/css-pseudo-classes.css.tags0000644000175000017500000000116314514252267017042 00000000000000a:lang(en):afterÌ2048Ö0 struct: a:lang(en):after body :not(span)Ì2048Ö0 struct: body :not(span) span:not(:first-child)Ì2048Ö0 struct: span:not(:first-child) span:nth-child(-n+3)Ì2048Ö0 struct: span:nth-child(-n+3) span:nth-child(0n+1)Ì2048Ö0 struct: span:nth-child(0n+1) span:nth-child(1)Ì2048Ö0 struct: span:nth-child(1) tr:nth-child(10n+0)Ì2048Ö0 struct: tr:nth-child(10n+0) tr:nth-child(2n)Ì2048Ö0 struct: tr:nth-child(2n) tr:nth-child(2n+1)Ì2048Ö0 struct: tr:nth-child(2n+1) tr:nth-child(even)Ì2048Ö0 struct: tr:nth-child(even) tr:nth-child(odd)Ì2048Ö0 struct: tr:nth-child(odd) geany-2.0/tests/ctags/simple.rb0000644000175000017500000000134414514252267013472 00000000000000#!/usr/bin/ruby module ModuleExample class ClassExample def class_method puts "in class_method" end def ClassExample.singleton_class_method puts "in singleton_class_method" end def class_method_exclamation! puts "in class_method_exclamation!" end def class_method_question? puts "in class_method_question?" end def `(command) return "just testing a backquote override" end end def module_method puts "in module_method" end def ModuleExample.singleton_module_method puts "in singleton_module_method" end end ModuleExample::ClassExample.singleton_class_method geany-2.0/tests/ctags/css-at-supports.css0000644000175000017500000000016214514252267015452 00000000000000 @supports ((test-property: 42) or (test-property2: 42)) { html { test-property: 42; } } html { color: blue; } geany-2.0/tests/ctags/classes.php0000644000175000017500000000056314514252267014024 00000000000000Expected output is classes: Bar Foo functions: __construct [Foo] __construct [Bar] method1 [Foo] method1 [Bar] method2 [Foo] const std::string func6(); const std::string var6 = "hello"; std::string func7(); std::string var7 = "hello"; /* this shows a different bug in the parser, adding scope std to the symbol. * ignore this for now. std::string const func8(); std::string const var8 = "hello"; */ geany-2.0/tests/ctags/simple.bas0000644000175000017500000000030714514252267013632 00000000000000Gosub start Const one = 1 Common a As Integer Dim b As Integer DIM AS STRING str Type test a As Integer b As Integer End Type Function f() a = 3 End Function start: f() Return geany-2.0/tests/ctags/matlab_backtracking.m0000644000175000017500000000564014514252267016000 00000000000000% http://www.math.washington.edu/~burke/crs/516/HTML/backtrack.html % Backtracking Linesearch function [xn,fn,fcall] = backtrack(xc,d,fc,fnc,DDfnc,c,gamma,eps) % %GENERAL DESCRIPTION % %This function performs the basic backtracking subroutine. %The subroutine requires the following input: % xc = the current point, % d = the direction of search, % fc = the current function value, % fnc = a string variable for the function name, % DDfnc = the directional derivative of fnc at xc in the % direction d, must have DDfnc < 0, % c = the slope modification parameter in (0,1), % gamma = the backstepping parameter in (0,1), % eps = the stopping criteria for norm(xn - xc), % that is, the main algorithm stops when % norm(xn - xc) <= eps. % %The routine returns % xn = the new point, % fn = the function value at the new point, % fnc = the number of calls to fnc. % %TERMINATION CRITERIA % %The backtracking is terminated if the step to the new point %xn is so small that it triggers termination in the main algorithm, %i.e. norm(xc - xn) <= eps. In this case we return xn = xc if %fn >= fc (we have not reduced the function value); otherwise, %we return xn. % %THE MATH % %The backtracking routing attempts to find a step size for %reducing the value of the function fnc given the current point xc %and a direction d. It does this by successively trying step sizes %of the form gamma^s for s = 0,1,2... to find the smallest %value of s for which the inequality % % fnc(xc+gamma^s*d)\le fnc(xc)+c*gamma^s*DD % % is satisfied. The new point to be returned is then given % by xn = xc+gamma^s*d. % %CHECK INPUT SPECIFICATIONS % if DDfnc >= 0, error('The backtracking subroutine has been sent a direction of nondesce nt. Program has been terminated.') end if c<= 0 | c>= 1, error('The slope modification parameter c in the backtracking subroutine is not in (0,1).') end if gamma<=0 | gamma >=1, error('The backtracking parameter gamma is not in (0,1).') end if eps <= 0, error('The termination criteria eps sent to the backtracking line search is not positive.') end % %CHECK DIMENSIONS % if size(xc)~=size(d) error('The vectors sent to backtrack are not of the same dimension.') end % % %EXECUTE THE LINE SEARCH % % xn = xc+d; cDDfnc = c*DDfnc; fn = feval(fnc,xn); fcall = 1 ; while fn > fc+cDDfnc, d = gamma*d; cDDfnc = gamma*cDDfnc; xn = xc+d; fn = feval(fnc,xn); fcall = fcall+1; %Check if the step to xn is too small. if norm(d) <= eps, disp('linesearch step too small') if fn >= fc, xn = xc; end break end end geany-2.0/tests/ctags/cobol/0000755000175000017500000000000014514253243013023 500000000000000geany-2.0/tests/ctags/cobol/helloworld.cbl0000644000175000017500000000215614514252267015611 00000000000000 00000* VALIDATION OF BASE COBOL INSTALL 00050000 01000 IDENTIFICATION DIVISION. 00060000 01100 PROGRAM-ID. 'HELLO'. 00070000 02000 ENVIRONMENT DIVISION. 00080000 02100 CONFIGURATION SECTION. 00090000 02110 SOURCE-COMPUTER. GNULINUX. 00100000 02120 OBJECT-COMPUTER. HERCULES. 00110000 02200 SPECIAL-NAMES. 00120000 02210 CONSOLE IS CONSL. 00130000 03000 DATA DIVISION. 00140000 04000 PROCEDURE DIVISION. 00150000 04100 00-MAIN. 00160000 04110 DISPLAY 'HELLO, WORLD' UPON CONSL. 00170000 04900 STOP RUN. 00180000 geany-2.0/tests/ctags/cobol/simple.cbl0000644000175000017500000000161214514252267014723 00000000000000 IDENTIFICATION DIVISION. PROGRAM-ID. Program-Name. AUTHOR. Darren Hiebert. ENVIRONMENT DIVISION. INPUT-OUPUT SECTION. FILE-CONTROL. SELECT File-Name ASSIGN TO "SAMPLE.DAT" ORGANIZATION IS LINE SEQUENTIAL. DATA DIVISION. FILE SECTION. FD File-Name. 01 File-Group-Name. 02 File-Data-Item PIC 9(7). WORKING-STORAGE SECTION. 01 Group-Name. 02 Data-Item1 PIC 9 VALUE ZEROS. 03 SH-WORK-MMDDYYYY PIC 9(08) VALUE 0. 03 SH-WORK-MMDDYYYY-2 REDEFINES SH-WORK-MMDDYYYY. 03 DW-DAYS-IN-MONTHS VALUE "312831303130313130313031". 05 DW-DAYS-IN-MONTH OCCURS 12 TIMES PIC 9(02). PROCEDURE DIVISION. Begin. STOP RUN. Subprogram-Name. geany-2.0/tests/ctags/cobol/helloworld2.cbl.tags0000644000175000017500000000065214514252267016627 0000000000000000-MAINÌ65536Ö0 macro: 00-MAIN CONFIGURATIONÌ256Ö0 namespace: CONFIGURATION DATAÌ32Ö0 interface: DATA ENVIRONMENTÌ32Ö0 interface: ENVIRONMENT HELLO WORLDÌ1Ö0 class: HELLO WORLD IDENTIFICATIONÌ32Ö0 interface: IDENTIFICATION OBJECT-COMPUTERÌ65536Ö0 macro: OBJECT-COMPUTER PROCEDUREÌ32Ö0 interface: PROCEDURE SOURCE-COMPUTERÌ65536Ö0 macro: SOURCE-COMPUTER SPECIAL-NAMESÌ65536Ö0 macro: SPECIAL-NAMES geany-2.0/tests/ctags/cobol/levels.cbl0000644000175000017500000000152314514252267014725 00000000000000 IDENTIFICATION DIVISION. PROGRAM-ID. Test-Items. DATA DIVISION. WORKING-STORAGE SECTION. 01 RECORD1. 05 ITEM1 PIC X(1). 05 ITEM2 PIC A(1). 88 ODD VALUES 1, 3, 5, 7, 9. 88 EVEN VALUES 2, 4, 6, 8. 05 ITEM3 PIC X(6). 66 RDITEM4 RENAMES ITEM1 THRU ITEM2. 66 RDITEM5 RENAMES ITEM1 THROUGH ITEM3. 77 STDLN1 PIC A(4). 01 REC2. 02 G1. 05 ITEM1 PICTURE X(10). 05 ITEM2 PIC X(10). 66 OTHERNAME1 RENAMES ITEM1 IN REC2. 66 OTHERNAME2 RENAMES G1. PROCEDURE DIVISION. MAIN-PROCEDURE. DISPLAY "Hello world". DISPLAY OTHERNAME2. STOP RUN. END PROGRAM Test-Items. geany-2.0/tests/ctags/cobol/quoted-program-id.cbl0000644000175000017500000000032614514252267016773 00000000000000 IDENTIFICATION DIVISION. PROGRAM-ID. 'Test program name'. PROCEDURE DIVISION. MAIN. DISPLAY 'This is a test program'. STOP RUN. END PROGRAM 'Test program name'. geany-2.0/tests/ctags/cobol/simple.cbl.tags0000644000175000017500000000226514514252267015665 00000000000000AUTHORÌ65536Ö0 macro: AUTHOR BeginÌ65536Ö0 macro: Begin DATAÌ32Ö0 interface: DATA DW-DAYS-IN-MONTHÌ16384ÎGroup-Name.Data-Item1.DW-DAYS-IN-MONTHSÖ0 variable: Group-Name.Data-Item1.DW-DAYS-IN-MONTHS :: DW-DAYS-IN-MONTH DW-DAYS-IN-MONTHSÌ16384ÎGroup-Name.Data-Item1Ö0 variable: Group-Name.Data-Item1 :: DW-DAYS-IN-MONTHS Data-Item1Ì16384ÎGroup-NameÖ0 variable: Group-Name :: Data-Item1 ENVIRONMENTÌ32Ö0 interface: ENVIRONMENT FILEÌ256Ö0 namespace: FILE FILE-CONTROLÌ65536Ö0 macro: FILE-CONTROL File-Data-ItemÌ16384ÎFile-Group-NameÖ0 variable: File-Group-Name :: File-Data-Item File-Group-NameÌ2048Ö0 struct: File-Group-Name File-NameÌ16Ö0 function: File-Name Group-NameÌ2048Ö0 struct: Group-Name IDENTIFICATIONÌ32Ö0 interface: IDENTIFICATION INPUT-OUPUTÌ256Ö0 namespace: INPUT-OUPUT PROCEDUREÌ32Ö0 interface: PROCEDURE Program-NameÌ1Ö0 class: Program-Name SH-WORK-MMDDYYYYÌ16384ÎGroup-Name.Data-Item1Ö0 variable: Group-Name.Data-Item1 :: SH-WORK-MMDDYYYY SH-WORK-MMDDYYYY-2Ì16384ÎGroup-Name.Data-Item1Ö0 variable: Group-Name.Data-Item1 :: SH-WORK-MMDDYYYY-2 Subprogram-NameÌ65536Ö0 macro: Subprogram-Name WORKING-STORAGEÌ256Ö0 namespace: WORKING-STORAGE geany-2.0/tests/ctags/cobol/levels.cbl.tags0000644000175000017500000000172414514252267015665 00000000000000DATAÌ32Ö0 interface: DATA EVENÌ16384ÎRECORD1.ITEM2Ö0 variable: RECORD1.ITEM2 :: EVEN G1Ì2048ÎREC2Ö0 struct: REC2 :: G1 IDENTIFICATIONÌ32Ö0 interface: IDENTIFICATION ITEM1Ì16384ÎREC2.G1Ö0 variable: REC2.G1 :: ITEM1 ITEM1Ì16384ÎRECORD1Ö0 variable: RECORD1 :: ITEM1 ITEM2Ì16384ÎREC2.G1Ö0 variable: REC2.G1 :: ITEM2 ITEM2Ì16384ÎRECORD1Ö0 variable: RECORD1 :: ITEM2 ITEM3Ì16384ÎRECORD1Ö0 variable: RECORD1 :: ITEM3 MAIN-PROCEDUREÌ65536Ö0 macro: MAIN-PROCEDURE ODDÌ16384ÎRECORD1.ITEM2Ö0 variable: RECORD1.ITEM2 :: ODD OTHERNAME1Ì16384ÎREC2Ö0 variable: REC2 :: OTHERNAME1 OTHERNAME2Ì16384ÎREC2Ö0 variable: REC2 :: OTHERNAME2 PROCEDUREÌ32Ö0 interface: PROCEDURE RDITEM4Ì16384ÎRECORD1Ö0 variable: RECORD1 :: RDITEM4 RDITEM5Ì16384ÎRECORD1Ö0 variable: RECORD1 :: RDITEM5 REC2Ì2048Ö0 struct: REC2 RECORD1Ì2048Ö0 struct: RECORD1 STDLN1Ì16384Ö0 variable: STDLN1 Test-ItemsÌ1Ö0 class: Test-Items WORKING-STORAGEÌ256Ö0 namespace: WORKING-STORAGE geany-2.0/tests/ctags/cobol/quoted-program-id.cbl.tags0000644000175000017500000000024614514252267017731 00000000000000IDENTIFICATIONÌ32Ö0 interface: IDENTIFICATION MAINÌ65536Ö0 macro: MAIN PROCEDUREÌ32Ö0 interface: PROCEDURE Test program nameÌ1Ö0 class: Test program name geany-2.0/tests/ctags/cobol/helloworld2.cbl0000644000175000017500000000072714514252267015675 00000000000000 00000* VALIDATION OF BASE COBOL INSTALL IDENTIFICATION DIVISION. 01100 PROGRAM-ID. 'HELLO WORLD'. 02000 ENVIRONMENT DIV -ISION. 02100 CONFIGURATION SECTION. 02110 SOURCE-COMPUTER. GNULINUX. 02120 OBJECT-COMPUTER. HERCULES. 02200 SPECIAL --NAMES. 02210 CONSOLE IS CONSL. 03000 DATA DIVISION. 04000 PROCEDUR - E DIVISION. 04100 00-MAIN. 04110 DISPLAY 'HELLO, WORLD' UPON CONSL. 04900 STOP RUN. geany-2.0/tests/ctags/cobol/helloworld.cbl.tags0000644000175000017500000000063614514252267016547 0000000000000000-MAINÌ65536Ö0 macro: 00-MAIN CONFIGURATIONÌ256Ö0 namespace: CONFIGURATION DATAÌ32Ö0 interface: DATA ENVIRONMENTÌ32Ö0 interface: ENVIRONMENT HELLOÌ1Ö0 class: HELLO IDENTIFICATIONÌ32Ö0 interface: IDENTIFICATION OBJECT-COMPUTERÌ65536Ö0 macro: OBJECT-COMPUTER PROCEDUREÌ32Ö0 interface: PROCEDURE SOURCE-COMPUTERÌ65536Ö0 macro: SOURCE-COMPUTER SPECIAL-NAMESÌ65536Ö0 macro: SPECIAL-NAMES geany-2.0/tests/ctags/maze.erl0000644000175000017500000001022714514252267013314 00000000000000-module(maze). -vsn('2002.0317'). -author('cpressey@catseye.mb.ca'). -copyright('Copyright (c)2002 Cat`s Eye Technologies. All rights reserved.'). %%% Redistribution and use in source and binary forms, with or without %%% modification, are permitted provided that the following conditions %%% are met: %%% %%% Redistributions of source code must retain the above copyright %%% notice, this list of conditions and the following disclaimer. %%% %%% Redistributions in binary form must reproduce the above copyright %%% notice, this list of conditions and the following disclaimer in %%% the documentation and/or other materials provided with the %%% distribution. %%% %%% Neither the name of Cat's Eye Technologies nor the names of its %%% contributors may be used to endorse or promote products derived %%% from this software without specific prior written permission. %%% %%% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND %%% CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, %%% INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF %%% MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE %%% DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE %%% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, %%% OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, %%% PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, %%% OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON %%% ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, %%% OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY %%% OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE %%% POSSIBILITY OF SUCH DAMAGE. -include("maze.hrl"). -export([build/0, generate/1]). %%% BEGIN maze.erl %%% %%% A simple maze-drawing program. %% Driver function ----------------------------------------------------- build() -> Tot = generate(#maze{}), tot_print(Tot). %% Maze generation function -------------------------------------------- generate(#maze{}=M) -> seed(), {X, Y} = {random:uniform(M#maze.width div 2) * 2, random:uniform(M#maze.height div 2) * 2}, R2 = tot_put(X, Y, tot_new(M#maze.width, M#maze.height, M#maze.wall), M#maze.space), generate(M, R2, X, Y). generate(#maze{}=M, R, X, Y) -> lists:foldl(fun({DX, DY}, A) -> NX = X + DX * 2, NY = Y + DY * 2, W = M#maze.wall, case catch tot_get(NX, NY, A) of W -> M1 = tot_put(X + DX, Y + DY, A, M#maze.space), M2 = tot_put(NX, NY, M1, M#maze.space), generate(M, M2, NX, NY); _ -> A end end, R, scramble([{-1,0}, {1,0}, {0,-1}, {0,1}])). %%% ToT (Tuple-of-Tuples) Utilities ------------------------------------ tot_new(W, H, Cell) -> erlang:make_tuple(H, erlang:make_tuple(W, Cell)). tot_get(X, Y, Tot) -> element(X, element(Y, Tot)). tot_put(X, Y, Tot, V) -> setelement(Y, Tot, setelement(X, element(Y, Tot), V)). tot_print(ToT) -> tot_print(1, ToT). tot_print(Y, ToT) when Y =< size(ToT) -> tot_print_tuple(element(Y, ToT)), io:fwrite("~n"), tot_print(Y+1, ToT); tot_print(Y, ToT) -> ok. tot_print_tuple(T) -> tot_print_tuple(1, T). tot_print_tuple(X, T) when X =< size(T) -> io:fwrite("~s", [[element(X, T)]]), tot_print_tuple(X+1, T); tot_print_tuple(X, T) -> ok. %%% Randomness Functions ----------------------------------------------- %% Seed the random number generator so that it will produce unpredictable %% values. Should be called once at startup, before using random numbers. seed() -> {H,M,S} = time(), random:seed(S,M,H), random:uniform(23). % prime the pump - first number can be iffy %% Pick a random element from a tuple or a list (equal chance for every %% element.) pick(Tuple) when tuple(Tuple) -> pick(tuple_to_list(Tuple)); pick(List) -> lists:nth(random:uniform(length(List)), List). %% Mix up the order (shuffle or scramble) a tuple or list. scramble(Tuple) when tuple(Tuple) -> list_to_tuple(scramble(tuple_to_list(Tuple))); scramble(List) -> scramble(List, []). scramble([], Acc) -> Acc; scramble(List, Acc) -> S = pick(List), scramble(List -- [S], Acc ++ [S]). %%% END of maze.erl %%% geany-2.0/tests/ctags/bug1938565.sql.tags0000644000175000017500000000041014514252267014665 00000000000000demo_pkgÌ512Ö0 package: demo_pkg func1Ì16Îdemo_pkgÖ0 function: demo_pkg :: func1 func1_protoÌ1024Îdemo_pkgÖ0 prototype: demo_pkg :: func1_proto func2Ì16Îdemo_pkgÖ0 function: demo_pkg :: func2 func2_protoÌ1024Îdemo_pkgÖ0 prototype: demo_pkg :: func2_proto geany-2.0/tests/ctags/namelist.f.tags0000644000175000017500000000003514514252267014570 00000000000000mainÌ2048Ö0 struct: main geany-2.0/tests/ctags/bug961001.v0000644000175000017500000000126114514252267013277 00000000000000/* * In Verilog, the following two lines are both valid syntax: * * `define GUEST * `define GUEST * * The first defines "GUEST" as existing, but with no assigned * value. The second defines "GUEST" as existing with an * assigned value. Ctags55 correctly handles both cases, but * Ctags551 - Ctags554 only handles the `define with value * correctly. Here is some test code to demonstrate this: */ `define HOSTA `define HOSTB `define HOSTC `define HOSTD `define GUESTA 1 `define GUESTB 2 `define GUESTC 3 `define GUESTD 4 /* * Ctags55 correctly generates a tag for all `defines in the * code, but Ctags554 does not generate tags for "HOSTB" * or "HOSTD". */ geany-2.0/tests/ctags/bug1575055.cpp0000644000175000017500000000007614514252267013712 00000000000000namespace TheNamespace { class MyClass { }; int variable; } geany-2.0/tests/ctags/keyword_virtual.cs0000644000175000017500000000256714514252267015445 00000000000000// cs_virtual_keyword.cs // Virtual and override using System; class TestClass { public class Dimensions { public const double pi = Math.PI; protected double x, y; public Dimensions() { } public Dimensions (double x, double y) { this.x = x; this.y = y; } public virtual double Area() { return x*y; } } public class Circle: Dimensions { public Circle(double r): base(r, 0) { } public override double Area() { return pi * x * x; } } class Sphere: Dimensions { public Sphere(double r): base(r, 0) { } public override double Area() { return 4 * pi * x * x; } } class Cylinder: Dimensions { public Cylinder(double r, double h): base(r, h) { } public override double Area() { return 2*pi*x*x + 2*pi*x*y; } } public static void Main() { double r = 3.0, h = 5.0; Dimensions c = new Circle(r); Dimensions s = new Sphere(r); Dimensions l = new Cylinder(r, h); // Display results: Console.WriteLine("Area of Circle = {0:F2}", c.Area()); Console.WriteLine("Area of Sphere = {0:F2}", s.Area()); Console.WriteLine("Area of Cylinder = {0:F2}", l.Area()); } } geany-2.0/tests/ctags/py_constructor_arglist.py.tags0000644000175000017500000000355014514252267020006 00000000000000HttpResponseÌ32768Îdjango.httpÖ0 externvar: django.http :: HttpResponse HttpResponseBadRequestÌ32768Îdjango.httpÖ0 externvar: django.http :: HttpResponseBadRequest InterfaceDataValidationErrorÌ32768Îvnstat.api.errorÖ0 externvar: vnstat.api.error :: InterfaceDataValidationError RequestContextÌ32768Îdjango.template.contextÖ0 externvar: django.template.context :: RequestContext SomeClassÌ1Ö0 class: SomeClass __init__Ì128Í(self, filename, pathsep='', treegap=64)ÎSomeClassÖ0 method: SomeClass :: __init__(self, filename, pathsep='', treegap=64) bsddbÌ32768Ö0 externvar: bsddb btopenÌ32768ÎbsddbÖ0 externvar: bsddb :: btopen csrf_exemptÌ32768Îdjango.views.decorators.csrfÖ0 externvar: django.views.decorators.csrf :: csrf_exempt csrf_exempt2Ì32768Îdjango.views.decorators.csrfÖ0 externvar: django.views.decorators.csrf :: csrf_exempt2 django.contrib.auth.decoratorsÌ32768Ö0 externvar: django.contrib.auth.decorators django.httpÌ32768Ö0 externvar: django.http django.shortcutsÌ32768Ö0 externvar: django.shortcuts django.template.contextÌ32768Ö0 externvar: django.template.context django.utilsÌ32768Ö0 externvar: django.utils django.views.decorators.csrfÌ32768Ö0 externvar: django.views.decorators.csrf django.views.decorators.httpÌ32768Ö0 externvar: django.views.decorators.http login_requiredÌ32768Îdjango.contrib.auth.decoratorsÖ0 externvar: django.contrib.auth.decorators :: login_required permission_requiredÌ32768Îdjango.contrib.auth.decoratorsÖ0 externvar: django.contrib.auth.decorators :: permission_required render_to_responseÌ32768Îdjango.shortcutsÖ0 externvar: django.shortcuts :: render_to_response require_POSTÌ32768Îdjango.views.decorators.httpÖ0 externvar: django.views.decorators.http :: require_POST simplejsonÌ32768Îdjango.utilsÖ0 externvar: django.utils :: simplejson sysÌ32768Ö0 externvar: sys vnstat.api.errorÌ32768Ö0 externvar: vnstat.api.error geany-2.0/tests/ctags/keyword_implicit.cs.tags0000644000175000017500000000055214514252267016516 00000000000000DigitÌ128Í(byte value)ÎDigitÖ0 method: Digit :: Digit(byte value) DigitÌ2048Ö0 struct: Digit MainÌ128Í()ÎTestÖ0Ïpublic void method: public void Test :: Main() TestÌ1Ö0 class: Test operator byteÌ128Í(Digit d)ÎDigitÖ0Ïpublic implicit method: public implicit Digit :: operator byte(Digit d) valueÌ8ÎDigitÖ0Ïbyte field: byte Digit :: value geany-2.0/tests/ctags/keyword_event.cs0000644000175000017500000000645014514252267015073 00000000000000// event_keyword.cs using System; public delegate void MyDelegate(); // delegate declaration public interface I { event MyDelegate MyEvent; void FireAway(); } public class MyClass: I { public event MyDelegate MyEvent; public void FireAway() { if (MyEvent != null) MyEvent(); } } public class MainClass { static private void f() { Console.WriteLine("This is called when the event fires."); } static public void Main () { I i = new MyClass(); i.MyEvent += new MyDelegate(f); i.FireAway(); } } // event_keyword2.cs using System; using System.Collections; public delegate void MyDelegate1(int i); public delegate void MyDelegate2(string s); public delegate void MyDelegate3(int i, object o); public delegate void MyDelegate4(); public class PropertyEventsSample { private Hashtable eventTable = new Hashtable(); public event MyDelegate1 Event1 { add { eventTable["Event1"] = (MyDelegate1)eventTable["Event1"] + value; } remove { eventTable["Event1"] = (MyDelegate1)eventTable["Event1"] - value; } } public event MyDelegate1 Event2 { add { eventTable["Event2"] = (MyDelegate1)eventTable["Event2"] + value; } remove { eventTable["Event2"] = (MyDelegate1)eventTable["Event2"] - value; } } public event MyDelegate2 Event3 { add { eventTable["Event3"] = (MyDelegate2)eventTable["Event3"] + value; } remove { eventTable["Event3"] = (MyDelegate2)eventTable["Event3"] - value; } } public event MyDelegate3 Event4 { add { eventTable["Event4"] = (MyDelegate3)eventTable["Event4"] + value; } remove { eventTable["Event4"] = (MyDelegate3)eventTable["Event4"] - value; } } public event MyDelegate3 Event5 { add { eventTable["Event5"] = (MyDelegate3)eventTable["Event5"] + value; } remove { eventTable["Event5"] = (MyDelegate3)eventTable["Event5"] - value; } } public event MyDelegate4 Event6 { add { eventTable["Event6"] = (MyDelegate4)eventTable["Event6"] + value; } remove { eventTable["Event6"] = (MyDelegate4)eventTable["Event6"] - value; } } } public class MyClass { public static void Main() { } } // event_keyword3.cs using System; public delegate void MyDelegate1(); public interface I1 { event MyDelegate1 MyEvent; } public delegate int MyDelegate2(string s); public interface I2 { event MyDelegate2 MyEvent; } public class ExplicitEventsSample: I1, I2 { public event MyDelegate1 MyEvent; // normal implementation of I1.MyEvent. event MyDelegate2 I2.MyEvent // explicit implementation of I2.MyEvent { add { MyEvent2Storage += value; } remove { MyEvent2Storage -= value; } } private MyDelegate2 MyEvent2Storage; // underlying storage for I2.MyEvent. private void FireEvents() { if (MyEvent != null) MyEvent(); if (MyEvent2Storage != null) MyEvent2Storage("hello"); } } public class MyClass { public static void Main() { } } geany-2.0/tests/ctags/prototype.h.tags0000644000175000017500000000022614514252267015025 00000000000000prototype_aÌ1024Í(int a,char * b)Ö0Ïint prototype: int prototype_a(int a,char * b) prototype_bÌ1024Í(void)Ö0Ïvoid prototype: void prototype_b(void) geany-2.0/tests/ctags/bug639644.hpp0000644000175000017500000000172114514252267013641 00000000000000/* Date: Sun, 17 Nov 2002 04:57:43 -0800 Subject: [ ctags-Bugs-639644 ] anonymous namespaces in headers Bugs item #639644, was opened at 2002-11-17 13:57 You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=106556&aid=639644&group_id=6556 Category: None Group: None Status: Open Resolution: None Priority: 5 Submitted By: Matthias S. Benkmann (mbenkmann) Assigned to: Nobody/Anonymous (nobody) Summary: anonymous namespaces in headers Initial Comment: --------------------temp3.h---------------- */ namespace { int foo; } /* --------------------------------------------- > ctags -f - temp3.h foo temp3.h /^ int foo;$/;" m namespace: That last field should be "namespace:" and the kind field should be variable, not member. ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=106556&aid=639644&group_id=6556 */ geany-2.0/tests/ctags/bug726712.f900000644000175000017500000000353114514252267013442 00000000000000! Bugs item #726712, was opened at 2003-04-24 08:36 ! Message generated for change (Comment added) made by schubidu ! You can respond by visiting: ! https://sourceforge.net/tracker/?func=detail&atid=106556&aid=726712&group_id=6556 ! ! Category: None ! Group: None ! Status: Open ! Resolution: None ! Priority: 5 ! Submitted By: sandra schrödter (schubidu) ! Assigned to: Darren Hiebert (dhiebert) ! Summary: ctags 5.5 and f90: "endsubroutine" not recognized ! ! Initial Comment: ! Dear Ctags'ers. :) ! ! First of all: good tool! :) I stumbled across ctags for ! my gvim6, wanted to use the nice plugin taglist. ! ! My System: HP-Unix and ctags 5.5 ! ! My problem is the following. The command: ! ! "ctags tagstest.f90" ! ! builds a tagsfile that lacks 1 of the declared 3 ! subroutines. ! The problem disappears when the declaration of the ! subroutine ends in "end subroutine" and not in ! "endsubroutine", although "endsubroutine" is correct ! Fortran90 syntax, AFAIK. ! ! Is there a chance to get this corrected? ! ! ! The example file tagstest.f90: subroutine tagstest_ctrl() real :: a a = 0.0 call sub1( a) call sub2( a) endsubroutine tagstest_ctrl subroutine sub1( a) real,intent( inout) ::a a = 1.1 endsubroutine sub1 subroutine sub2( a) real,intent( inout) ::a a = 2.2 endsubroutine sub2 ! ---------------------------------------------------------------------- ! ! Comment By: sandra schrödter (schubidu) ! Date: 2003-05-28 13:17 ! ! Message: ! Logged In: YES ! user_id=763447 ! ! I realized that there are also problems when a subroutine ! ends only with the keyword ! end ! ! The following subroutine is listed but cannot be selected ! (that is, the cursor wont go there) ! ! ---------------------------------------------------------------------- geany-2.0/tests/ctags/value.f.tags0000644000175000017500000000017114514252267014071 00000000000000aaÌ16384ÎfigureÖ0 variable: figure :: aa figÌ16384ÎfigureÖ0 variable: figure :: fig figureÌ2048Ö0 struct: figure geany-2.0/tests/ctags/keyword_private.cs.tags0000644000175000017500000000065514514252267016362 00000000000000AccessSalaryÌ128Í()ÎEmployeeÖ0Ïpublic double method: public double Employee :: AccessSalary() EmployeeÌ1Ö0 class: Employee MainÌ128Í()ÎMainClassÖ0Ïpublic void method: public void MainClass :: Main() MainClassÌ1Ö0 class: MainClass nameÌ8ÎEmployeeÖ0 field: Employee :: name not_visibleÌ8ÎEmployeeÖ0Ïint field: int Employee :: not_visible salaryÌ8ÎEmployeeÖ0Ïdouble field: double Employee :: salary geany-2.0/tests/ctags/bug1988027.py.tags0000644000175000017500000000003414514252267014516 00000000000000dummyÌ1Ö0 class: dummy geany-2.0/tests/ctags/interface_properties.cs.tags0000644000175000017500000000066614514252267017362 00000000000000EmployeeÌ1Ö0 class: Employee EmployeeÌ128Í()ÎEmployeeÖ0 method: Employee :: Employee() IEmployeeÌ32Ö0 interface: IEmployee MainÌ128Í()ÎMainClassÖ0Ïpublic void method: public void MainClass :: Main() MainClassÌ1Ö0 class: MainClass counterÌ8ÎEmployeeÖ0Ïint field: int Employee :: counter nameÌ8ÎEmployeeÖ0 field: Employee :: name numberOfEmployeesÌ8ÎEmployeeÖ0Ïint field: int Employee :: numberOfEmployees geany-2.0/tests/ctags/bug1111214-j-chan.v0000644000175000017500000000014114514252267014503 00000000000000/* * **/ module top(outsig, insig); output outsig; input insig; assign outsig = insig; endmodule geany-2.0/tests/ctags/cxx11-final.cpp0000644000175000017500000000032514514252267014411 00000000000000class Base { public: virtual void foo() = 0; }; class Derived final : public Base { virtual void foo() final; virtual void final(); }; void Base::foo() { } void Derived::foo() { } void Derived::final() { } geany-2.0/tests/ctags/bug3168705.py0000644000175000017500000000014714514252267013561 00000000000000class A: def func1(): """this is a comment""" pass def func2(): pass geany-2.0/tests/ctags/objectivec_property.mm.tags0000644000175000017500000000030314514252267017217 00000000000000PersonÌ32Ö0 interface: Person initWithAge:Ì128Í(int)ÎPersonÖ0 method: Person :: initWithAge:(int) m_ageÌ8ÎPersonÖ0 field: Person :: m_age m_nameÌ8ÎPersonÖ0 field: Person :: m_name geany-2.0/tests/ctags/test.erl0000644000175000017500000000041114514252267013331 00000000000000-module(test). -export([function1/0, function1/2]). -type type1() :: binary(). -record(record1, {name :: list(), value :: list()}). -define(DEFINE_1, function1()). -define(DEFINE_2(A, B), function2(A, B)). function1() -> ok. function1(A, B) -> A + B. geany-2.0/tests/ctags/non-ascii-ident1.php0000644000175000017500000000030014514252267015416 00000000000000r = $a * $b; } public function __toString() { return (string) $this->r; } } echo new ×(2, 2); geany-2.0/tests/ctags/bug1575055.cpp.tags0000644000175000017500000000026414514252267014646 00000000000000MyClassÌ1ÎTheNamespaceÖ0 class: TheNamespace :: MyClass TheNamespaceÌ256Ö0 namespace: TheNamespace variableÌ16384ÎTheNamespaceÖ0Ïint variable: int TheNamespace :: variable geany-2.0/tests/ctags/infinite_loop.java0000644000175000017500000000002414514252267015347 00000000000000class C { void maingeany-2.0/tests/ctags/rules.t2t0000644000175000017500000005374214514252267013452 00000000000000Txt2tags Markup Rules %!includeconf: rules.conf This document describes all the details about each txt2tags mark. The target audience are **experienced** users. You may find it useful if you want to master the marks or solve a specific problem about a mark. If you are new to txt2tags or just want to know which are the available marks, please read the [Markup Demo MARKUPDEMO]. Note 1: This document is generated directly from the txt2tags test-suite. All the rules mentioned here are 100% in sync with the current program code. Note 2: A good practice is to consult [the sources rules.t2t] when reading, to see how the texts were made. Table of Contents: %%TOC ------------------------------------------------------------- = Paragraph =[paragraph] %INCLUDED(t2t) starts here: ../../../test/marks/paragraph.t2t BODYINIT %%% Syntax: Lines grouped together A paragraph is composed by one or more lines. A blank line (or a table, or a list) ends the current paragraph. %%% Syntax: Leading and trailing spaces are ignored Leading and trailing spaces are ignored. %%% Syntax: A comment don't close a paragraph A comment line can be placed inside a paragraph. % this comment will be ignored It will not affect it. %%% Closing: EOF closes the open paragraph The end of the file (EOF) closes the currently open paragraph. = Comment =[comment] %INCLUDED(t2t) starts here: ../../../test/marks/comment.t2t BODYINIT %%% Syntax: The % character at the line beginning (column 1) %glued with the % mark % separated from the % mark % very distant from the % mark %%%%%%% lots of % marks % a blank comment, used for vertical spacing: % % NOTE: what matters is the first % being at the line beginning, % the rest of the line is just ignored. %%% Syntax: Area (block) %%% You're not seeing this. %%% %%% Syntax: Area (block) with trailing spaces %%% You're not seeing this. %%% %%% Invalid: The % in any other position % not on the line beginning (at column 2) some text % half line comments are not allowed = Line =[line] %INCLUDED(t2t) starts here: ../../../test/marks/line.t2t BODYINIT %%% Syntax: At least 20 chars of - = _ -------------------- ==================== ____________________ %%% Syntax: Any kind of mixing is allowed %% Free mixing is allowed to make the line, %% but the first char is the identifier for %% the difference between separator ( - _ ) %% and strong ( = ) lines. =========----------- -_-_-_-_-_-_-_-_-_-_ =-=-=-=-=-=-=-=-=-=- =------------------= --------====-------- %%% Syntax: Leading and/or trailing spaces are allowed -------------------- -------------------- -------------------- %%% Invalid: Less than 20 chars (but strike matches) --------- %%% Invalid: Strange chars (but strike matches) --------- ---------- ---------+---------- ( -------------------- ) = Inline =[inline] %INCLUDED(t2t) starts here: ../../../test/marks/inline.t2t BODYINIT %%% Syntax: Marks are greedy and must be "glued" with contents %% GLUED: The contents must be glued with the marks, no spaces %% between them. Right after the opening mark there must be a %% non-blank character, as well as right before the closing mark. %% %% GREEDY: If the contents boundary character is the same as %% the mark character, it is considered contents, not mark. %% So ""****bold****"" turns to ""**bold**"" in HTML. i) **b** //i// __u__ --s-- ``m`` ""r"" ''t'' i) **bo** //it// __un__ --st-- ``mo`` ""ra"" ''tg'' i) **bold** //ital// __undr__ --strk-- ``mono`` ""raw"" ''tggd'' i) **bo ld** //it al// __un dr__ --st rk-- ``mo no`` ""r aw"" ''tg gd'' i) **bo * ld** //it / al// __un _ dr__ --st - rk-- ``mo ` no`` ""r " aw"" ''tg ' gd'' i) **bo **ld** //it //al// __un __dr__ --st --rk-- ``mo ``no`` ""r ""aw"" ''tg ''gd'' i) **bo ** ld** //it // al// __un __ dr__ --st -- rk-- ``mo `` no`` ""r "" aw"" ''tg '' gd'' i) ****bold**** ////ital//// ____undr____ ----strk---- ````mono```` """"raw"""" ''''tggd'''' i) ***bold*** ///ital/// ___undr___ ---strk--- ```mono``` """raw""" '''tggd''' %%% Syntax: Repetition is greedy %% When the mark character is repeated many times, %% the contents are expanded to the largest possible. %% Thats why they are greedy, the outer marks are %% the ones used. i) ***** ///// _____ ----- ````` """"" ''''' i) ****** ////// ______ ------ `````` """""" '''''' i) ******* /////// _______ ------- ``````` """"""" ''''''' i) ******** //////// ________ -------- ```````` """""""" '''''''' i) ********* ///////// _________ --------- ````````` """"""""" ''''''''' i) ********** ////////// __________ ---------- `````````` """""""""" '''''''''' %%% Invalid: No contents i) **** //// ____ ---- ```` """" '''' i) ** ** // // __ __ -- -- `` `` "" "" '' '' %%% Invalid: Contents not "glued" with marks %% Spaces between the marks and the contents in any side %% invalidate the mark. i) ** bold** // ital// __ undr__ -- strk-- `` mono`` "" raw"" '' tggd'' i) **bold ** //ital // __undr __ --strk -- ``mono `` ""raw "" ''tggd '' i) ** bold ** // ital // __ undr __ -- strk -- `` mono `` "" raw "" '' tggd '' = Link =[link] %INCLUDED(t2t) starts here: ../../../test/marks/link.t2t BODYINIT %%% Syntax: E-mail user@domain.com user@domain.com. user@domain.com. any text. any text: user@domain.com. any text. [label user@domain.com] %%% Syntax: E-mail with form data user@domain.com?subject=bla user@domain.com?subject=bla. user@domain.com?subject=bla, user@domain.com?subject=bla&cc=otheruser@domain.com user@domain.com?subject=bla&cc=otheruser@domain.com. user@domain.com?subject=bla&cc=otheruser@domain.com, [label user@domain.com?subject=bla&cc=otheruser@domain.com]. [label user@domain.com?subject=bla&cc=otheruser@domain.com.]. %%% Syntax: URL http://www.domain.com http://www.domain.com/dir/ http://www.domain.com/dir/// http://www.domain.com. http://www.domain.com, http://www.domain.com. any text. http://www.domain.com, any text. http://www.domain.com/dir/. any text. any text: http://www.domain.com. any text. any text: http://www.domain.com/dir/. any text. any text: http://www.domain.com/dir/index.html. any text. any text: http://www.domain.com/dir/index.html, any text. %%% Syntax: URL with anchor http://www.domain.com/dir/#anchor http://www.domain.com/dir/index.html#anchor http://www.domain.com/dir/index.html#anchor. http://www.domain.com/dir/#anchor. any text. http://www.domain.com/dir/index.html#anchor. any text. any text: http://www.domain.com/dir/#anchor. any text. any text: http://www.domain.com/dir/index.html#anchor. any text. %%% Syntax: URL with form data http://domain.com?a=a@a.a&b=a+b+c. http://domain.com?a=a@a.a&b=a+b+c, http://domain.com/bla.cgi?a=a@a.a&b=a+b+c. http://domain.com/bla.cgi?a=a@a.a&b=a+b+c@. %%% Syntax: URL with form data and anchor http://domain.com?a=a@a.a&b=a+b+c.#anchor http://domain.com/bla.cgi?a=a@a.a&b=a+b+c.#anchor http://domain.com/bla.cgi?a=a@a.a&b=a+b+c@.#anchor %%% Syntax: URL with login data http://user:password@domain.com/bla.html. http://user:password@domain.com/dir/. http://user:password@domain.com. http://user:@domain.com. http://user@domain.com. %%% Syntax: URL with login, form and anchor http://user:password@domain.com/bla.cgi?a=a@a.a&b=a+b+c.#anchor http://user:password@domain.com/bla.cgi?a=a@a.a&b=a+b+c@#anchor %%% Syntax: URL with label [label www.domain.com] %%% Syntax: URL with label (trailing spaces are discarded, leading are maintained) %TODO normalize this behavior [ label www.domain.com] [label www.domain.com] %%% Syntax: URL with label, stressing [anchor http://www.domain.com/dir/index.html#anchor.] [login http://user:password@domain.com/bla.html] [form http://www.domain.com/bla.cgi?a=a@a.a&b=a+b+c.] [form & anchor http://www.domain.com/bla.cgi?a=a@a.a&b=a+b+c.#anchor] [login & form http://user:password@domain.com/bla.cgi?a=a@a.a&b=a+b+c.] %%% Syntax: Link with label for local files [local link up ..] [local link file bla.html] [local link anchor #anchor] [local link file/anchor bla.html#anchor] [local link file/anchor bla.html#anchor.] [local link img abc.gif] %%% Syntax: Another link as a label [www.fake.com www.domain.com] %%% Syntax: URL with funny chars http://domain.com:8080/~user/_st-r@a=n$g,e/index%20new.htm http://domain.com:8080/~user/_st-r@a=n$g,e/index%20new.htm?a=/%22&b=+.@*_- http://domain.com:8080/~user/_st-r@a=n$g,e/index%20new.htm?a=/%22&b=+.@*_-#anchor_-1%. http://foo._user-9:pass!#$%&*()+word@domain.com:8080/~user/_st-r@a=n$g,e/index%20new.htm?a=/%22&b=+.@*_-#anchor_-1%. %%% Test: Various per line http://L1.com ! L2@www.com ! [L3 www.com] ! [L4 w@ww.com] ! www.L5.com %%% Feature: Guessed link, adding protocol automatically www.domain.com www2.domain.com ftp.domain.com WWW.DOMAIN.COM FTP.DOMAIN.COM [label www.domain.com] [label ftp.domain.com] [label WWW.DOMAIN.COM] [label FTP.DOMAIN.COM] %%% Invalid: Trailing space on link [label www.domain.com ] %%% Invalid: Label with ] char (use postproc) [label] www.domain.com] = Image =[image] %INCLUDED(t2t) starts here: ../../../test/marks/image.t2t BODYINIT %%% Syntax: Image name inside brackets: [img] [img.png] %%% Syntax: Image pointing to a link: [[img] link] [[img.png] http://txt2tags.org] %%% Align: Image position is preserved when inside paragraph [img.png] Image at the line beginning. Image in the middle [img.png] of the line. Image at the line end. [img.png] %%% Align: Image alone with spaces around is aligned [img.png] [img.png] [img.png] %%% Test: Two glued images with no spaces (left & right) [img.png][img.png] %%% Test: Various per line Images [img.png] mixed [img.png] with [img.png] text. Images glued together: [img.png][img.png][img.png]. %%% Invalid: Spaces inside are not allowed [img.png ] [ img.png] [ img.png ] = Macro =[macro] %INCLUDED(t2t) starts here: ../../../test/marks/macro.t2t BODYINIT %%% Syntax: Macro without formatting string Date : %%date - %%date() Mtime : %%mtime - %%mtime() Infile : %%infile - %%infile() Outfile : %%outfile - %%outfile() %%% Syntax: Macro name is case insensitive Date : %%dAtE Mtime : %%mTiMe Infile : %%iNfIlE Outfile : %%oUtFiLe %%% Syntax: Macro with formatting string Date : %%date(txt %C txt) Mtime : %%mtime(txt %C txt) Infile : %%infile(txt %e txt) Outfile : %%outfile(txt %e txt) %%% Syntax: Leading and trailing spaces are preserved Date : (%%date( txt )) - (%%date( %C )) Mtime : (%%mtime( txt )) - (%%mtime( %C )) Infile : (%%infile( txt )) - (%%infile( %e )) Outfile : (%%outfile( txt )) - (%%outfile( %e )) %%% Test: Expansion of the percent char Date : %%date(%) - %%date(%%) - %%date(%%%) - %%date(%%%) Mtime : %%mtime(%) - %%mtime(%%) - %%mtime(%%%) - %%mtime(%%%) Infile : %%infile(%) - %%infile(%%) - %%infile(%%%) - %%infile(%%%) Outfile : %%outfile(%) - %%outfile(%%) - %%outfile(%%%) - %%outfile(%%%) %%% Test: Various per line, glued Date : %%date(%C)%%date%%date Mtime : %%mtime(%C)%%mtime%%mtime Infile : %%infile(%e)%%infile%%infile Outfile : %%outfile(%e)%%outfile%%outfile %%% Test: Path formatters Path : %%infile(%p) Path : %%outfile(%p) Dirname : %%infile(%d, %D) Dirname : %%outfile(%d, %D) File : %%infile(%F + %e = %f) File : %%outfile(%F + %e = %f) = Numbered Title =[numtitle] See [Title #title], the same rules apply. = Title =[title] %INCLUDED(t2t) starts here: ../../../test/marks/title.t2t BODYINIT %%% Syntax: Balanced equal signs (from 1 to 5) = Title Level 1 = == Title Level 2 == === Title Level 3 === ==== Title Level 4 ==== ===== Title Level 5 ===== %%% Label: Between brackets, alphanumeric [A-Za-z0-9_-] = Title Level 1 =[lab_el-1] == Title Level 2 ==[lab_el-2] === Title Level 3 ===[lab_el-3] ==== Title Level 4 ====[lab_el-4] ===== Title Level 5 =====[lab_el-5] %%% Syntax: Spaces around and/or inside are allowed (and ignored) ===Title Level 3=== === Title Level 3 === === Title Level 3 === === Title Level 3 === === Title Level 3 === === Title Level 3 ===[lab_el-9] %%% Invalid: Unbalanced equal signs =Not Title ==Not Title= ===Not Title==== %%% Invalid: Level deeper than 5 ======Not Title 6====== =======Not Title 7======= %%% Invalid: Space between title and label =Not Title= [label1] %%% Invalid: Space inside label =Not Title=[ label ] %%% Invalid: Strange chars inside label =Not Title=[la/bel] = Quote =[quote] %INCLUDED(t2t) starts here: ../../../test/marks/quote.t2t BODYINIT %%% Syntax: TAB defines quote To quote a paragraph, just prefix it by a TAB character. All the lines of the paragraph must begin with a TAB. Any non-tabbed line closes the quote block. %%% Nesting: Creating deeper quotes The number of leading TABs identifies the quote block depth. This is quote level 1. With two TABs, we are on the quote level 2. The more TABs, more deep is the quote level. There isn't a limit. %%% Nesting: Reverse nesting works This quote starts at level 4. Then its depth is decreased. Counting down, one by one. Until the level 1. %%% Nesting: Random count Unlike lists, any quote block is independent, not part of a tree. The TAB count don't need to be incremental by one. The nesting don't need to follow any rule. Quotes can be opened and closed in any way. You choose. %%% Nesting: When not supported Some targets (as sgml) don't support the nesting of quotes. There is only one quote level. In this case, no matter how much TABs are used to define the quote block, it always will be level 1. %%% Syntax: Spaces after TAB Spaces AFTER the TAB character are allowed. But be careful, it can be confusing. %%% Invalid: Spaces before TAB Spaces BEFORE the TAB character invalidate the mark. It's not quote. %%% Invalid: Paragraphs inside Paragraph breaks inside a quote aren't possible. This sample are two separated quoted paragraphs, not a quote block with two paragraphs inside. %%% Closing: EOF closes the open block The end of the file (EOF) closes the currently open quote block. = Raw =[raw] See [Verbatim #verbatim], the same rules apply. = Verbatim =[verbatim] %INCLUDED(t2t) starts here: ../../../test/marks/verbatim.t2t BODYINIT %%% Syntax: A single line ``` A verbatim line. %%% Syntax: A single line with leading spaces ``` Another verbatim line, with leading spaces. %%% Syntax: Area (block) ``` A verbatim area delimited by lines with marks. ``` %%% Syntax: Area (block) with trailing spaces ``` Trailing spaces and TABs after the area marks are allowed, but not encouraged nor documented. ``` %%% Invalid: No space between mark and contents ```Not a verbatim line, need one space after mark. %%% Invalid: Leading spaces on block marks ``` Not a verbatim area. The marks must be at the line beginning, no leading spaces. ``` %%% Closing: EOF closes the open block ``` The end of the file (EOF) closes the currently open verbatim area. ``` = Definition List =[deflist] See [List #list], the same rules apply. = Numbered List =[numlist] See [List #list], the same rules apply. = List =[list] %INCLUDED(t2t) starts here: ../../../test/marks/list.t2t BODYINIT %%% Items: Prefixed by hyphen - Use the hyphen to prefix list items. - There must be one space after the hyphen. - The list is closed by two consecutive blank lines. %%% Items: Free leading spacing (indentation) - The list can be indented on the source document. - You can use any number of spaces. - The result will be the same. %%% Items: Vertical spacing between items - Let one blank line between the list items. - It will be maintained on the conversion. - Some targets don't support this behavior. - This one was separated by a line with blanks. You can also put a blank line inside the item contents and it will be preserved. %%% Items: Exactly ONE space after the hyphen -This is not a list (no space) - This is not a list (more than one space) - This is not a list (a TAB instead the space) %%% Items: Catchy cases - - This is a list - + This is a list - : This is a list %%% Nesting: Creating sublists - This is the "mother" list first item. - Here is the second, but inside this item, - there is a sublist, with its own items. - Note that the items of the same sublist - must have the same indentation. - And this can go on, opening sublists. - Just add leading spaces before the - hyphen and sublists will be opened. - The two blank lines closes them all. %%% Nesting: Free leading spacing (indentation) - When nesting lists, the additional spaces are free. - You can add just one, - or many. - What matters is to put more than the previous. - But remember that the other items of the same list - must use the same indentation. %%% Nesting: Maximum depth - There is not a depth limit, - you can go deeper and deeper. - But some targets may have restrictions. - The LaTeX maximum is here, 4 levels. - This one and the following sublists - are moved up to the level 4 - when converting to LaTeX. - On the other targets, - it is just fine - to have a very deep list. %%% Nesting: Reverse doesn't work - Reverse nesting doesn't work. - Because a sublist *must* have a mother list. - It's the list concept, not a txt2tags limitation. - All this sublists will be bumped to mother lists. - At level 1, like this one. %%% Nesting: Going deeper and back %% When nesting back to an upper level, the previous sublist %% is automatically closed. - Level 1 - Level 2 - Level 3 - Level 4 - Level 3 -- (closed Level 4) - Level 2 -- (closed Level 3) - Level 1 -- (closed Level 2) %% More than one list can be closed when nesting back. - Level 1 - Level 2 - Level 3 - Level 4 - Level 1 -- (closed Level 4, Level 3 and Level 2) %%% Nesting: Vertical spacing between lists - Level 1 - Level 2 -- blank BEFORE and AFTER (in) - Level 3 % comment lines are NOT considered blank lines - Level 4 % comment lines are NOT considered blank lines - Level 3 - Level 2 -- blank BEFORE and AFTER (out) - Level 1 - Level 2 -- blank BEFORE (spaces) and AFTER (TAB) - Level 3 %%% Nesting: Messing up %% Be careful when going back on the nesting, %% it must be on a valid level! If not, it will %% be bumped up to the previous valid level. - Level 1 - Level 2 - Level 3 - Level 4 - Level 3.5 ??? - Level 3 - Level 2.5 ??? - Level 2 - Level 1.5 ??? - Level 1 %%% Closing: Two (not so) empty lines - This list is closed by a line with spaces and other with TABs - This list is NOT closed by two comment lines % comment lines are NOT considered blank lines % comment lines are NOT considered blank lines - This list is closed by a line with spaces and TAB, - then a comment line, then an empty line. % comment lines are NOT considered blank lines %%% Closing: Empty item closes current (sub)list %% The two blank lines closes ALL the lists. %% To close just the current, use an empty item. - Level 1 - Level 2 - Level 3 - Level 2 - Level 1 - %% The empty item can have trailing blanks. - Empty item with trailing spaces. - - Empty item with trailing TAB. - %%% Closing: EOF closes the lists - If the end of the file (EOF) is hit, - all the currently opened list are closed, - just like when using the two blank lines. = Table =[table] %INCLUDED(t2t) starts here: ../../../test/marks/table.t2t BODYINIT %%% Syntax: Lines starting with a pipe | | Cell 1 %%% Syntax: Extra pipes separate cells | Cell 1 | Cell 2 | Cell 3 %%% Syntax: With a trailing pipe, make border | Cell 1 | Cell 2 | Cell 3 | %%% Syntax: Table lines starting with double pipe are heading || Cell 1 | Cell 2 | Cell 3 | %%% Align: Spaces before the leading pipe centralize the table | Cell 1 | Cell 2 | Cell 3 | %%% Align: Spaces inside the cell denote its alignment || Heading | Heading | Heading | % comments don't close an opened table | <- | -- | -> | | -- | -- | -- | | -> | -- | <- | %%% Span: Column span is defined by extra pipes at cell closing || 1 | 2 | 3+4 || | 1 | 2 | 3 | 4 | | 1+2+3 ||| 4 | | 1 | 2+3 || 4 | | 1+2+3+4 |||| %%% Test: Empty cells are placed as expected | 0 | 1 | 2 | | | 4 | 5 | | 7 | | 8 | | A | B | | | D | E | F | %%% Test: Lines with different number of cells | 1 | | 1 | 2 | | 1 | 2 | 3 | | 1 | 2 | 3 | 4 | | 1 | 2 | 3 | 4 | 5 | %%% Test: Empty cells + Span + Messy cell number = Fun! | Jan | | Fev || | Mar ||| | Apr |||| | May ||||| | 20% | 40% | 60% | 80% | 100% | | | | / | | | | | / / / / / ||| | | / / / / / / / / / ||||| | | o | | o | | | | | . | | | | | = = = = ||| | | 01 | 02 | | | 05 | | 07 | | | | | 11 | | 13 | | | 16 | | 17 | | 19 | 20 | | | 23 | | | 25 | 26 | | | 29 | 30 | | 32 | | | | 35 | | 37 | | 39 | 40 | %%% Test: Lots of cells at the same line | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F | %%% Test: Empty lines | | | | | | %%% Invalid: There must be at least one space around the pipe |this|is|not|a|table| |this| is| not| a| table| |this |is |not |a |table | %%% Invalid: You must use spaces, not TABs | this | is | not | a | table | ------------------------------------------------------------ The End. geany-2.0/tests/ctags/directives.c0000644000175000017500000000162114514252267014157 00000000000000/* Test simple cases */ #define VARIABLE_LIKE some_value #define FUNCTION_LIKE(a,b) (a + b) #pragma weak WeakSymbol = StrongSymbol #define with_long_comment /* line 1 line 2 */ /* Test usual case */ #ifdef MY_MACRO # define MACRO_TO_SEE1 1 int a; #elif YOUR_MACRO # define MACRO_TO_SEE2 2 int b; #elif defined (THEIR_MACRO) # define MACRO_TO_SEE3 3 int c; #else # define MACRO_TO_SEE4 4 int d; #endif /* Test commented-out case */ #if 0 #define IGNORE_MACRO int e; # if 0 # define ANOTHER_IGNORE_MACRO int f; # else # define YAIM # endif #else # define SEE_THIS_MACRO 1 int g; #endif /* Test path selection algorithm */ #ifdef OK #define PATH1 int foo1 (void) { #elif defined (OK) #define PATH2 int foo2 (void) { #else #define PATH3 int foo3 (void) { #endif } int bar1 (void) { #ifdef OK #define PATH1b } int p1; #elif defined (OK) #define PATH2b } int p2; #else #define PATH3b } int p3; #endif geany-2.0/tests/ctags/keyword_names.f90.tags0000644000175000017500000000046714514252267016005 00000000000000DataÌ1ÎProgramÖ0 class: Program :: Data InterfaceÌ2048Ö0 struct: Interface MyFuncÌ16ÎProgramÖ0 function: Program :: MyFunc ProgramÌ32ÎProgramÖ0 interface: Program :: Program ProgramÌ256Ö0 namespace: Program contentsÌ64ÎDataÖ0 member: Data :: contents iÌ16384ÎProgramÖ0 variable: Program :: i geany-2.0/tests/ctags/3184782.sql.tags0000644000175000017500000000037214514252267014172 00000000000000do_this_stuffÌ256Îp_testÖ0 namespace: p_test :: do_this_stuff myfn1Ì256Îp_testÖ0 namespace: p_test :: myfn1 myfn2Ì256Îp_testÖ0 namespace: p_test :: myfn2 p_testÌ512Ö0 package: p_test process_thisÌ256Îp_testÖ0 namespace: p_test :: process_this geany-2.0/tests/ctags/ada-overriding.ads0000644000175000017500000000214114514252267015234 00000000000000-- Taken from #2382 submitted by @JulienPivard -- @summary -- Implémentation par une tâche. -- @description -- Implémentation par une tache de la classe synchronisé. -- @group Version tâche -- -- package Carte_P.Tasche_P package Input with Pure => False, Preelaborate => False, Elaborate_Body => True, Spark_Mode => Off is --------------------------------------------------------------------------- task type Tasche_T is new Carte_T with -- Implémentation par une tâche de l'interface Carte_T. ----------------------------------- overriding entry Coucou; -- Implémentation par un accept. ----------------------------------- -- overriding -- entry Inutile; -- Implémentation par un accept. -- @param This -- La carte. end Tasche_T; --------------------------------------------------------------------------- overriding procedure Inutile (This : in out Tasche_T); -- Implémentation par une procédure. -- @param This -- La carte. end Carte_P.Tasche_P; geany-2.0/tests/ctags/bug2747828.v0000644000175000017500000000004314514252267013401 00000000000000parameter ramaddr_0 = {1'b1,9'd0}; geany-2.0/tests/ctags/bug1585745.cpp0000644000175000017500000000034114514252267013714 00000000000000// Despite the weird whitespace, all these destructors should be recognized and tagged. Class1::~Class1() { } Class2::~ Class2() { } Class3:: ~Class3() { } Class4:: ~ Class4() { } class Class5 { public: ~ Class5() { } }; geany-2.0/tests/ctags/readlob.sql0000644000175000017500000000230414514252267014002 00000000000000rem ----------------------------------------------------------------------- rem URL: http://www.orafaq.com/scripts/plsql/readlob.txt rem Filename: readlob.sql rem Purpose: Fetch LOB column values piece-wise from PL/SQL rem Date: 12-Jun-2000 rem Author: Frank Naude (frank@ibi.co.za) rem ----------------------------------------------------------------------- set serveroutput on DROP TABLE lob_table; -- Create table to hols LOBs CREATE TABLE lob_table ( id INTEGER, b_lob BLOB, c_lob CLOB, b_file BFILE ); INSERT INTO lob_table -- Create sample record VALUES (1, EMPTY_BLOB(), 'abcde', NULL); DECLARE clob_locator CLOB; charbuf VARCHAR2(20); read_offset INTEGER; read_amount INTEGER; BEGIN -- First we need to get the lob locator SELECT c_lob INTO clob_locator FROM lob_table WHERE id = 1; DBMS_OUTPUT.PUT_LINE('CLOB Size: ' || DBMS_LOB.GETLENGTH(clob_locator)); -- Read LOB field contents read_offset := 1; read_amount := 20; dbms_lob.read(clob_locator, read_amount, read_offset, charbuf); dbms_output.put_line('CLOB Value: ' || charbuf); END; / geany-2.0/tests/ctags/test_input2.rs0000644000175000017500000000132614514252267014502 00000000000000#![cfg(not(test))] fn not_hashbang() {} pub fn foo_bar_test_func(apples:fruit::SomeStruct,(oranges,lemon):(isize,isize))->isize{ let some_var_name=2*oranges; let a=SomeLongStructName{v:0}; println!("{}", "a"); veg::another_function(apples.red_value,oranges,lemon); some_var_name-apples.red_value+lemon+a.v } pub mod fruit { pub struct SomeStruct{ pub red_value: isize, pub green_value: isize, pub blue_value: isize } } fn free_func() { } impl SomeLongStructName { fn fooo() { } fn baaz() { } } pub struct SomeLongStructName {v:isize} mod veg{ pub fn another_function(a:isize,b:isize,c:isize)->isize { a+b+c } } mod mineral { fn granite() { } fn limestone() { } fn chalk() { } } fn main() {} geany-2.0/tests/ctags/process_order.c.tags0000644000175000017500000000042014514252267015620 00000000000000I1_E1Ì4Îanon_enum_1Ö0 enumerator: anon_enum_1 :: I1_E1 I1_E2Ì4Îanon_enum_1Ö0 enumerator: anon_enum_1 :: I1_E2 I2_E1Ì4Îanon_enum_1Ö0 enumerator: anon_enum_1 :: I2_E1 I2_E2Ì4Îanon_enum_1Ö0 enumerator: anon_enum_1 :: I2_E2 anon_enum_1Ì2Ö1 enum: anon_enum_1 flags: 1 geany-2.0/tests/ctags/simple.zep0000644000175000017500000000042214514252267013661 00000000000000/* from http://zephir-lang.com/language.html */ namespace Test; class MyClass { public function someMethod1() { int a = 1, b = 2; return a + b; } public function someMethod2() { int a = 3, b = 4; return a + b; } } geany-2.0/tests/ctags/bug1764143.h0000644000175000017500000000104114514252267013346 00000000000000static inline void omap1_arch_reset(char mode) { /* * Workaround for 5912/1611b bug mentioned in sprz209d.pdf p. 28 * "Global Software Reset Affects Traffic Controller Frequency". */ if (cpu_is_omap5912()) { omap_writew(omap_readw(DPLL_CTL) & ~(1 << 4), DPLL_CTL); omap_writew(0x8, ARM_RSTCT1); } if (machine_is_voiceblue()) voiceblue_reset(); else omap_writew(1, ARM_RSTCT1); } static inline void arch_reset(char mode) { if (!cpu_is_omap24xx()) omap1_arch_reset(mode); else omap_prcm_arch_reset(mode); } #endif geany-2.0/tests/ctags/vhdl-process.vhd.tags0000644000175000017500000000201414514252267015720 00000000000000StackTraceBufferÌ1Ö0 class: StackTraceBuffer arch_StackTraceBufferÌ2048ÎStackTraceBufferÖ0 struct: StackTraceBuffer :: arch_StackTraceBuffer i_clkÌ16384ÎStackTraceBufferÖ0 variable: StackTraceBuffer :: i_clk i_raddrÌ16384ÎStackTraceBufferÖ0 variable: StackTraceBuffer :: i_raddr i_waddrÌ16384ÎStackTraceBufferÖ0 variable: StackTraceBuffer :: i_waddr i_wdataÌ16384ÎStackTraceBufferÖ0 variable: StackTraceBuffer :: i_wdata i_weÌ16384ÎStackTraceBufferÖ0 variable: StackTraceBuffer :: i_we o_rdataÌ16384ÎStackTraceBufferÖ0 variable: StackTraceBuffer :: o_rdata raddrÌ16384ÎStackTraceBuffer.arch_StackTraceBufferÖ0 variable: StackTraceBuffer.arch_StackTraceBuffer :: raddr ram_typeÌ4096ÎStackTraceBuffer.arch_StackTraceBufferÖ0 typedef: StackTraceBuffer.arch_StackTraceBuffer :: ram_type regsÌ64ÎStackTraceBuffer.arch_StackTraceBufferÖ0 member: StackTraceBuffer.arch_StackTraceBuffer :: regs stackbufÌ16384ÎStackTraceBuffer.arch_StackTraceBufferÖ0 variable: StackTraceBuffer.arch_StackTraceBuffer :: stackbuf geany-2.0/tests/ctags/namespaces2.php0000644000175000017500000000112214514252267014560 00000000000000Tests for namespaces (unbraced version) Expected output is namespaces: Bar\Baz Foo classes: B [Bar\Baz] C [Foo] functions: __construct [Foo::C] __construct [Bar\Baz::B] a [Foo] a [Bar\Baz] b [Foo] c [Bar\Baz::B] d [Foo::C] 3; LABEL: __END__ sub IgnoreSub {} geany-2.0/tests/ctags/bug1773926.cpp.tags0000644000175000017500000000031414514252267014651 00000000000000ERROR_HAPPENEDÌ65536Ö0 macro: ERROR_HAPPENED NEXT_DEFINEÌ65536Ö0 macro: NEXT_DEFINE OKÌ65536Ö0 macro: OK mainÌ16Í(int argc,char * argv[])Ö0Ïint function: int main(int argc,char * argv[]) geany-2.0/tests/ctags/bug639644.hpp.tags0000644000175000017500000000021114514252267014567 00000000000000anon_namespace_1Ì256Ö1 namespace: anon_namespace_1 flags: 1 fooÌ16384Îanon_namespace_1Ö0Ïint variable: int anon_namespace_1 :: foo geany-2.0/tests/ctags/runner.sh0000754000175000017500000000204614514252267013523 00000000000000#!/bin/bash # error out on undefined variable expansion, useful for debugging set -u GEANY="$1" PRINTER="${top_srcdir:-../..}"/scripts/print-tags.py TMPDIR=$(mktemp -d) || exit 99 CONFDIR="$TMPDIR/config/" trap 'rm -rf "$TMPDIR"' EXIT # make sure we don't use an old or modified system version of the filetype # related configuration files mkdir -p "$CONFDIR" || exit 99 mkdir -p "$CONFDIR/filedefs/" || exit 99 cp "${top_srcdir:-../..}"/data/filetype_extensions.conf "$CONFDIR" || exit 99 cp "${top_srcdir:-../..}"/data/filedefs/filetypes.* "$CONFDIR/filedefs/" || exit 99 shift if [ "$1" = "--result" ]; then # --result $result $source... [ $# -gt 2 ] || exit 99 shift result="$1" shift source="$1" else # result is $1 and source is inferred from result result="$1" source="${result%.*}" fi shift tagfile="$TMPDIR/test.${source##*.}.tags" outfile="$TMPDIR/test.${source##*.}.out" "$GEANY" -c "$CONFDIR" -P -g "$tagfile" "$source" "$@" || exit 1 cat "$tagfile" | "$PRINTER" > "$outfile" || exit 3 diff -u "$result" "$outfile" || exit 2 geany-2.0/tests/ctags/keyword_const.cs.tags0000644000175000017500000000107514514252267016033 00000000000000ConstTestÌ1Ö0 class: ConstTest MainÌ128Í()ÎConstTestÖ0Ïpublic void method: public void ConstTest :: Main() MyClassÌ1ÎConstTestÖ0 class: ConstTest :: MyClass MyClassÌ128Í(int p1, int p2)ÎConstTest.MyClassÖ0 method: ConstTest.MyClass :: MyClass(int p1, int p2) c1Ì8ÎConstTest.MyClassÖ0Ïconst int field: const int ConstTest.MyClass :: c1 c2Ì8ÎConstTest.MyClassÖ0Ïconst int field: const int ConstTest.MyClass :: c2 xÌ8ÎConstTest.MyClassÖ0Ïint field: int ConstTest.MyClass :: x yÌ8ÎConstTest.MyClassÖ0Ïint field: int ConstTest.MyClass :: y geany-2.0/tests/ctags/bug670433.f90.tags0000644000175000017500000000023414514252267014372 00000000000000barÌ128Í(n)ÎfoobarÖ0 method: foobar :: bar(n) fÌ16ÎfooÖ0 function: foo :: f fooÌ16ÎfoobarÖ0 function: foobar :: foo foobarÌ256Ö0 namespace: foobar geany-2.0/tests/ctags/simple.ksh0000644000175000017500000000004614514252267013652 00000000000000#!/bin/ksh f1() { } function f2 { } geany-2.0/tests/ctags/bug1466117.c.tags0000644000175000017500000000021114514252267014274 00000000000000aÌ64ÎmystructÖ0Ïint member: int mystruct :: a bÌ64ÎmystructÖ0Ïint member: int mystruct :: b mystructÌ2048Ö0 struct: mystruct geany-2.0/tests/ctags/1880687.js.tags0000644000175000017500000000264114514252267014015 00000000000000MyClassÌ1Ö0 class: MyClass MyClass_sub1Ì128Í(x)ÎMyClassÖ0 method: MyClass :: MyClass_sub1(x) MyClass_sub2Ì128Í(x)ÎMyClassÖ0 method: MyClass :: MyClass_sub2(x) aÌ16Í(flag)Ö0 function: a(flag) aaÌ16Í()Ö0 function: aa() aa_sub1Ì16Í()ÎaaÖ0 function: aa :: aa_sub1() aa_sub2Ì16Í()ÎaaÖ0 function: aa :: aa_sub2() bÌ16Í()Ö0 function: b() bazÌ16Í()ÎfÖ0 function: f :: baz() cÌ16Í(flag)Ö0 function: c(flag) dÌ16Í()Ö0 function: d() eÌ16Í(flag)Ö0 function: e(flag) fÌ16Í()Ö0 function: f() gÌ16Í(flag)Ö0 function: g(flag) hÌ16Í()Ö0 function: h() iÌ16Í(flag)Ö0 function: i(flag) jÌ16Í()Ö0 function: j() kÌ16Í(flag)Ö0 function: k(flag) lÌ16Í()Ö0 function: l() mÌ16Í(flag)Ö0 function: m(flag) nÌ16Í()Ö0 function: n() oÌ16Í()Ö0 function: o() pÌ16Í()Ö0 function: p() qÌ16Í()Ö0 function: q() rÌ16Í(flag)Ö0 function: r(flag) sÌ16Í()Ö0 function: s() tÌ16Í(flag)Ö0 function: t(flag) uÌ16Í(flag)Ö0 function: u(flag) vÌ16Í(flag)Ö0 function: v(flag) wÌ16Í()Ö0 function: w() w_sub1Ì16Í(x)ÎwÖ0 function: w :: w_sub1(x) w_sub2Ì16Í()ÎwÖ0 function: w :: w_sub2() xÌ16Í()Ö0 function: x() x_sub1Ì16Í()ÎxÖ0 function: x :: x_sub1() x_sub2Ì16Í()ÎxÖ0 function: x :: x_sub2() yÌ16Í()Ö0 function: y() y_sub1Ì16Í()ÎyÖ0 function: y :: y_sub1() y_sub2Ì16Í()ÎyÖ0 function: y :: y_sub2() zÌ16Í()Ö0 function: z() z_sub1Ì16Í()ÎzÖ0 function: z :: z_sub1() z_sub2Ì16Í()ÎzÖ0 function: z :: z_sub2() geany-2.0/tests/ctags/bug699171.py.tags0000644000175000017500000000016214514252267014436 00000000000000HEADER_TEMPLATEÌ16384Ö0 variable: HEADER_TEMPLATE QuitÌ16Í(msg, exitcode=0)Ö0 function: Quit(msg, exitcode=0) geany-2.0/tests/ctags/bug2781264.rb0000644000175000017500000000020414514252267013526 00000000000000 class Foo def foo File.open("foo", "r") do |infile| infile.readline end end def bar print "bar" end end geany-2.0/tests/ctags/bug1770479.cpp.tags0000644000175000017500000000020214514252267014645 00000000000000fooÌ16Í(int i)Ö0Ïint function: int foo(int i) mainÌ16Í(int argc,char ** argv)Ö0Ïint function: int main(int argc,char ** argv) geany-2.0/tests/ctags/ada-package-generic.ads.tags0000644000175000017500000000104014514252267017023 00000000000000BlueÌ4ÎPrimary_ColorÖ0 enumerator: Primary_Color :: Blue ConversionsÌ512ÎMy_PackageÖ0 package: My_Package :: Conversions From_Big_RealÌ1024ÎConversionsÖ0 prototype: Conversions :: From_Big_Real GreenÌ4ÎPrimary_ColorÖ0 enumerator: Primary_Color :: Green Missing_TagÌ4096ÎMy_PackageÖ0 typedef: My_Package :: Missing_Tag My_PackageÌ512Ö0 package: My_Package NumÌ64ÎMissing_TagÖ0 member: Missing_Tag :: Num Primary_ColorÌ4096ÎMy_PackageÖ0 typedef: My_Package :: Primary_Color RedÌ4ÎPrimary_ColorÖ0 enumerator: Primary_Color :: Red geany-2.0/tests/ctags/bug1466117.c0000644000175000017500000000013414514252267013343 00000000000000typedef struct mystruct { int a; int b; }; typedef struct { int a; int b; } mystruct; geany-2.0/tests/ctags/property.cs.tags0000644000175000017500000000062114514252267015021 00000000000000EmployeeÌ1Ö0 class: Employee EmployeeÌ128Í()ÎEmployeeÖ0 method: Employee :: Employee() MainÌ128Í()ÎMainClassÖ0Ïpublic void method: public void MainClass :: Main() MainClassÌ1Ö0 class: MainClass counterÌ8ÎEmployeeÖ0Ïint field: int Employee :: counter nameÌ8ÎEmployeeÖ0 field: Employee :: name numberOfEmployeesÌ8ÎEmployeeÖ0Ïint field: int Employee :: numberOfEmployees geany-2.0/tests/ctags/bug1111214-j-chan.v.tags0000644000175000017500000000016014514252267015441 00000000000000insigÌ16384ÎtopÖ0 variable: top :: insig outsigÌ16384ÎtopÖ0 variable: top :: outsig topÌ1Ö0 class: top geany-2.0/tests/ctags/bug1809024.py.tags0000644000175000017500000000005414514252267014505 00000000000000detachÌ16Í(self)Ö0 function: detach(self) geany-2.0/tests/ctags/ada-adb.adb0000644000175000017500000000366514514252267013605 00000000000000-- Taken from altivec of GNAT examples (http://www.adacore.com/developers/code-samples/gnat-examples/) -- ==================================================================================================== -- This example shows how to create and manipulate vectors by the mean of high -- level views. with GNAT.Altivec; use GNAT.Altivec; with GNAT.Altivec.Conversions; use GNAT.Altivec.Conversions; with GNAT.Altivec.Vector_Operations; use GNAT.Altivec.Vector_Operations; with GNAT.Altivec.Vector_Types; use GNAT.Altivec.Vector_Types; with GNAT.Altivec.Vector_Views; use GNAT.Altivec.Vector_Views; with GNAT.IO; use GNAT.IO; procedure Altivec is View_A : constant VUI_View := (Values => (1, 2, 3, 4)); Vector_A : constant vector_unsigned_int := To_Vector (View_A); View_B : constant VUI_View := (Values => (1, 1, 1, 1)); Vector_B : constant vector_unsigned_int := To_Vector (View_B); Vector_C : vector_unsigned_int; View_C : VUI_View; begin Vector_C := vec_add (Vector_A, Vector_B); -- C = A + B View_C := To_View (Vector_C); for I in View_C.Values'Range loop Put_Line (unsigned_int'Image (View_C.Values (I))); end loop; end Altivec; procedure Greet is type Days is (Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday); -- Declaration of a subtype subtype Weekend_Days is Days range Saturday .. Sunday; -- ^ Constraint of the subtype M : Days := Sunday; S : Weekend_Days := M; -- No error here, Days and Weekend_Days -- are of the same type. begin for I in Days loop case I is -- Just like a type, a subtype can -- be used as a range when Weekend_Days => Put_Line ("Week end!"); when others => Put_Line ("Hello on " & Days'Image (I)); end case; end loop; end Greet;geany-2.0/tests/ctags/angle_bracket.cpp0000644000175000017500000000027214514252267015140 00000000000000static void foo (int nelem) { int rsize = 2; while (nelem < 0) { rsize <<= 1; } } static void bar (int value) { return value < 0 ? value : 3; } static bar2 (void) { } geany-2.0/tests/ctags/continuation.f90.tags0000644000175000017500000000025114514252267015637 00000000000000para_aÌ16384ÎtestÖ0 variable: test :: para_a para_bÌ16384ÎtestÖ0 variable: test :: para_b para_cÌ16384ÎtestÖ0 variable: test :: para_c testÌ256Ö0 namespace: test geany-2.0/tests/ctags/js-string-continuation.js.tags0000644000175000017500000000030014514252267017566 00000000000000firstÌ128Í()ÎoÖ0 method: o :: first() fourthÌ128Í()ÎoÖ0 method: o :: fourth() oÌ1Ö0 class: o secondÌ128Í()ÎoÖ0 method: o :: second() thirdÌ128Í()ÎoÖ0 method: o :: third() geany-2.0/tests/ctags/bug3168705.py.tags0000644000175000017500000000015014514252267014510 00000000000000AÌ1Ö0 class: A func1Ì128Í()ÎAÖ0 method: A :: func1() func2Ì128Í()ÎAÖ0 method: A :: func2() geany-2.0/tests/ctags/return-hint.zep0000644000175000017500000000030114514252267014643 00000000000000class Test { public function first(string str) -> string { function nested() { } } public function second(int i) -> int { } } geany-2.0/tests/ctags/3184782.sql0000644000175000017500000000134214514252267013233 00000000000000create or replace package body p_test is procedure do_this_stuff is begin if true then for idx in z+1 .. myarr.last loop if myarr.exists(idx) then null; end if; end loop; elsif true then for idx in myarr.first .. myarr.last loop if myarr.exists(idx) then null; end if; end loop; end if; end do_this_stuff; procedure process_this ( p_flag in boolean ) is begin null; end process_this; procedure myfn1 ( p_str1 in varchar2, p_str2 in varchar2 ) is begin process_this(false); end myfn1; procedure myfn2 ( p_str1 in varchar2, p_str2 in varchar2 ) is begin process_this(true); end myfn2; end p_test; geany-2.0/tests/ctags/case_sensitivity.php0000644000175000017500000000044214514252267015750 00000000000000 struct C { int x; }; struct D : ::C { D() { x = 123; } ~D() { std::cout << x << std::endl; } }; int main(void) { D d; return 0; } geany-2.0/tests/ctags/size_t_wchar_t_alias.d0000644000175000017500000000005214514252267016171 00000000000000 alias size_t = int; alias wchar_t = int; geany-2.0/tests/ctags/simple.hs0000644000175000017500000000031014514252267013471 00000000000000module Cards where data Int = -2147483648 | -2147483647 | ... | -1 | 0 | 1 | 2 | ... | 2147483647 newtype Fd = Fd CInt data Bool = True | False add :: Integer -> Integer -> Integer add x y = x + y geany-2.0/tests/ctags/bug665086.cpp.tags0000644000175000017500000000014214514252267014564 00000000000000C12Ì1ÎN1::N2Ö0 class: N1::N2 :: C12 N1Ì256Ö0 namespace: N1 N2Ì256ÎN1Ö0 namespace: N1 :: N2 geany-2.0/tests/ctags/structure.f0000644000175000017500000000157414514252267014070 00000000000000 program uninitialized_structure structure /weather/ integer month, day, year character*20 clouds real rainfall end structure record /weather/ latest end program initialized_structure structure /weather/ integer*1 month /08/, day /10/, year /89/ character*20 clouds /' overcast'/ real rainfall /3.12/ end structure record /weather/ latest print *, latest.month, latest.day, latest.year, + latest.clouds, latest.rainfall end program program nested_structure structure /top/ structure /nested/ level2 structure level3a, level3b integer a end structure end structure end structure end program geany-2.0/tests/ctags/bug1777344.java0000644000175000017500000000032514514252267014053 00000000000000import java.util.*; public class bug1777344 { private HashMap map1; private HashMap map2 = new HashMap(), map3; private boolean b = (1 < 3), c; private boolean d = 1 < 3, e; } geany-2.0/tests/ctags/68hc11.asm.tags0000644000175000017500000000046014514252267014223 00000000000000COLDÌ256Ö0 namespace: COLD INTERRUPTSÌ256Ö0 namespace: INTERRUPTS PORTDÌ65536Ö0 macro: PORTD PROMPTÌ256Ö0 namespace: PROMPT SPÌ65536Ö0 macro: SP TRAPPÌ256Ö0 namespace: TRAPP sym1Ì65536Ö0 macro: sym1 sym2Ì65536Ö0 macro: sym2 sym3Ì256Ö0 namespace: sym3 sym4Ì256Ö0 namespace: sym4 geany-2.0/tests/ctags/bug1086609.c.tags0000644000175000017500000000006414514252267014306 00000000000000func2Ì16Í(int a)Ö0Ïint function: int func2(int a) geany-2.0/tests/ctags/members.f900000644000175000017500000000057514514252267013633 00000000000000module Members implicit none type HasMembers ! a "derived type" in Fortran is analogous to a "class" in other languages integer, kind :: kind_member integer, len :: len_member integer :: member contains procedure :: MyMethod end type HasMembers contains subroutine MySubroutine(arg) ! ... end subroutine MySubroutine end module Members geany-2.0/tests/ctags/byte.f.tags0000644000175000017500000000073214514252267013723 00000000000000AÌ16384Îbyte_testÖ0 variable: byte_test :: A A1Ì16384Îbyte_testÖ0 variable: byte_test :: A1 A2Ì16384Îbyte_testÖ0 variable: byte_test :: A2 BÌ16384Îbyte_testÖ0 variable: byte_test :: B B1Ì16384Îbyte_testÖ0 variable: byte_test :: B1 B2Ì16384Îbyte_testÖ0 variable: byte_test :: B2 CÌ16384Îbyte_testÖ0 variable: byte_test :: C C1Ì16384Îbyte_testÖ0 variable: byte_test :: C1 C2Ì16384Îbyte_testÖ0 variable: byte_test :: C2 byte_testÌ2048Ö0 struct: byte_test geany-2.0/tests/ctags/array_spec.f900000644000175000017500000000054114514252267014322 00000000000000! Bug reported by Jim Chen on 31 Dec 2002 module Global_Variables implicit none ! Example of array-spec in entity-decl real*8, save :: & H (NDIM, NDIM) = 0.D0, & H0(NDIM, NDIM), & H1(NDIM, NDIM) = 0.D0, & H2(NDIM, NDIM) = 0.D0, & H3(NDIM, NDIM) = 0.D0, & H4(NDIM, NDIM) = 0.D0, & H5(NDIM, NDIM) = 0.D0 end module Global_Variables geany-2.0/tests/ctags/refcurs.sql.tags0000644000175000017500000000071014514252267014777 00000000000000get_cursor_refÌ16Îtest_ref_cursorÖ0 function: test_ref_cursor :: get_cursor_ref mainÌ256Îtest_ref_cursorÖ0 namespace: test_ref_cursor :: main mainÌ1024Îtest_ref_cursorÖ0 prototype: test_ref_cursor :: main process_cursorÌ256Îtest_ref_cursorÖ0 namespace: test_ref_cursor :: process_cursor process_cursorÌ1024Îtest_ref_cursorÖ0 prototype: test_ref_cursor :: process_cursor test_ref_cursorÌ512Ö0 package: test_ref_cursor typesÌ512Ö0 package: types geany-2.0/tests/ctags/ruby-doc.rb0000644000175000017500000000025014514252267013720 00000000000000def f0; end =begin def bug1 end =end def f1; end =begin def bug2 end =end def f2; end =begin def doesntcount end def bug3 end =end def notparsed end def f3; end geany-2.0/tests/ctags/js-unknown-construct-nesting.js0000644000175000017500000000041514514252267020010 00000000000000 var o = { aa: function () { foo: { return ; } }, bb: function (a) { switch (a) { case 1: if (1) { return 32 } break; case 2: return 31; } return 1; }, cc: function() {} }; geany-2.0/tests/ctags/make-gnumake-pattern-rules.mak0000644000175000017500000000007514514252267017513 00000000000000%.o: %.c touch $@ %.p %.q: %.d touch $@ %a b%: touch $@ geany-2.0/tests/ctags/bug1563476.cpp.tags0000644000175000017500000000023214514252267014645 00000000000000IntroduceBitDefÌ2048Ö0 struct: IntroduceBitDef fÌ16Í()ÎIntroduceBitDefÖ0Ïint function: int IntroduceBitDef :: f() gÌ16Í()Ö0Ïint function: int g() geany-2.0/tests/ctags/php5_5_class_kw.php0000644000175000017500000000022114514252267015344 00000000000000 on 4 Feb 2003 DOUBLE PRECISION FUNCTION DOPBL2( SUBNAM, M, N, KKL, KKU ) * * -- LAPACK timing routine (version 3.0) -- * Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., * Courant Institute, Argonne National Lab, and Rice University * June 30, 1999 * * .. Scalar Arguments .. CHARACTER*6 SUBNAM INTEGER KKL, KKU, M, N * .. * * Purpose * ======= * * DOPBL2 computes an approximation of the number of floating point * operations used by a subroutine SUBNAM with the given values * of the parameters M, N, KL, and KU. * * This version counts operations for the Level 2 BLAS. * * Arguments * ========= * * SUBNAM (input) CHARACTER*6 * The name of the subroutine. * * M (input) INTEGER * The number of rows of the coefficient matrix. M >= 0. * * N (input) INTEGER * The number of columns of the coefficient matrix. * If the matrix is square (such as in a solve routine) then * N is the number of right hand sides. N >= 0. * * KKL (input) INTEGER * The lower band width of the coefficient matrix. * KL is set to max( 0, min( M-1, KKL ) ). * * KKU (input) INTEGER * The upper band width of the coefficient matrix. * KU is set to max( 0, min( N-1, KKU ) ). * * ===================================================================== * * .. Local Scalars .. CHARACTER C1 CHARACTER*2 C2 CHARACTER*3 C3 DOUBLE PRECISION ADDS, EK, EM, EN, KL, KU, MULTS * .. * .. External Functions .. LOGICAL LSAME, LSAMEN EXTERNAL LSAME, LSAMEN * .. * .. Intrinsic Functions .. INTRINSIC MAX, MIN * .. * .. Executable Statements .. * * Quick return if possible * IF( M.LE.0 .OR. .NOT.( LSAME( SUBNAM, 'S' ) .OR. LSAME( SUBNAM, $ 'D' ) .OR. LSAME( SUBNAM, 'C' ) .OR. LSAME( SUBNAM, 'Z' ) ) ) $ THEN DOPBL2 = 0 RETURN END IF * C1 = SUBNAM( 1: 1 ) C2 = SUBNAM( 2: 3 ) C3 = SUBNAM( 4: 6 ) MULTS = 0 ADDS = 0 KL = MAX( 0, MIN( M-1, KKL ) ) KU = MAX( 0, MIN( N-1, KKU ) ) EM = M EN = N EK = KL * * ------------------------------- * Matrix-vector multiply routines * ------------------------------- * IF( LSAMEN( 3, C3, 'MV ' ) ) THEN * IF( LSAMEN( 2, C2, 'GE' ) ) THEN * MULTS = EM*( EN+1.D0 ) ADDS = EM*EN * * Assume M <= N + KL and KL < M * N <= M + KU and KU < N * so that the zero sections are triangles. * ELSE IF( LSAMEN( 2, C2, 'GB' ) ) THEN * MULTS = EM*( EN+1.D0 ) - ( EM-1.D0-KL )*( EM-KL ) / 2.D0 - $ ( EN-1.D0-KU )*( EN-KU ) / 2.D0 ADDS = EM*( EN+1.D0 ) - ( EM-1.D0-KL )*( EM-KL ) / 2.D0 - $ ( EN-1.D0-KU )*( EN-KU ) / 2.D0 * ELSE IF( LSAMEN( 2, C2, 'SY' ) .OR. LSAMEN( 2, C2, 'SP' ) .OR. $ LSAMEN( 3, SUBNAM, 'CHE' ) .OR. $ LSAMEN( 3, SUBNAM, 'ZHE' ) .OR. $ LSAMEN( 3, SUBNAM, 'CHP' ) .OR. $ LSAMEN( 3, SUBNAM, 'ZHP' ) ) THEN * MULTS = EM*( EM+1.D0 ) ADDS = EM*EM * ELSE IF( LSAMEN( 2, C2, 'SB' ) .OR. $ LSAMEN( 3, SUBNAM, 'CHB' ) .OR. $ LSAMEN( 3, SUBNAM, 'ZHB' ) ) THEN * MULTS = EM*( EM+1.D0 ) - ( EM-1.D0-EK )*( EM-EK ) ADDS = EM*EM - ( EM-1.D0-EK )*( EM-EK ) * ELSE IF( LSAMEN( 2, C2, 'TR' ) .OR. LSAMEN( 2, C2, 'TP' ) ) $ THEN * MULTS = EM*( EM+1.D0 ) / 2.D0 ADDS = ( EM-1.D0 )*EM / 2.D0 * ELSE IF( LSAMEN( 2, C2, 'TB' ) ) THEN * MULTS = EM*( EM+1.D0 ) / 2.D0 - $ ( EM-EK-1.D0 )*( EM-EK ) / 2.D0 ADDS = ( EM-1.D0 )*EM / 2.D0 - $ ( EM-EK-1.D0 )*( EM-EK ) / 2.D0 * END IF * * --------------------- * Matrix solve routines * --------------------- * ELSE IF( LSAMEN( 3, C3, 'SV ' ) ) THEN * IF( LSAMEN( 2, C2, 'TR' ) .OR. LSAMEN( 2, C2, 'TP' ) ) THEN * MULTS = EM*( EM+1.D0 ) / 2.D0 ADDS = ( EM-1.D0 )*EM / 2.D0 * ELSE IF( LSAMEN( 2, C2, 'TB' ) ) THEN * MULTS = EM*( EM+1.D0 ) / 2.D0 - $ ( EM-EK-1.D0 )*( EM-EK ) / 2.D0 ADDS = ( EM-1.D0 )*EM / 2.D0 - $ ( EM-EK-1.D0 )*( EM-EK ) / 2.D0 * END IF * * ---------------- * Rank-one updates * ---------------- * ELSE IF( LSAMEN( 3, C3, 'R ' ) ) THEN * IF( LSAMEN( 3, SUBNAM, 'SGE' ) .OR. $ LSAMEN( 3, SUBNAM, 'DGE' ) ) THEN * MULTS = EM*EN + MIN( EM, EN ) ADDS = EM*EN * ELSE IF( LSAMEN( 2, C2, 'SY' ) .OR. LSAMEN( 2, C2, 'SP' ) .OR. $ LSAMEN( 3, SUBNAM, 'CHE' ) .OR. $ LSAMEN( 3, SUBNAM, 'CHP' ) .OR. $ LSAMEN( 3, SUBNAM, 'ZHE' ) .OR. $ LSAMEN( 3, SUBNAM, 'ZHP' ) ) THEN * MULTS = EM*( EM+1.D0 ) / 2.D0 + EM ADDS = EM*( EM+1.D0 ) / 2.D0 * END IF * ELSE IF( LSAMEN( 3, C3, 'RC ' ) .OR. LSAMEN( 3, C3, 'RU ' ) ) THEN * IF( LSAMEN( 3, SUBNAM, 'CGE' ) .OR. $ LSAMEN( 3, SUBNAM, 'ZGE' ) ) THEN * MULTS = EM*EN + MIN( EM, EN ) ADDS = EM*EN * END IF * * ---------------- * Rank-two updates * ---------------- * ELSE IF( LSAMEN( 3, C3, 'R2 ' ) ) THEN IF( LSAMEN( 2, C2, 'SY' ) .OR. LSAMEN( 2, C2, 'SP' ) .OR. $ LSAMEN( 3, SUBNAM, 'CHE' ) .OR. $ LSAMEN( 3, SUBNAM, 'CHP' ) .OR. $ LSAMEN( 3, SUBNAM, 'ZHE' ) .OR. $ LSAMEN( 3, SUBNAM, 'ZHP' ) ) THEN * MULTS = EM*( EM+1.D0 ) + 2.D0*EM ADDS = EM*( EM+1.D0 ) * END IF END IF * * ------------------------------------------------ * Compute the total number of operations. * For real and double precision routines, count * 1 for each multiply and 1 for each add. * For complex and complex*16 routines, count * 6 for each multiply and 2 for each add. * ------------------------------------------------ * IF( LSAME( C1, 'S' ) .OR. LSAME( C1, 'D' ) ) THEN * DOPBL2 = MULTS + ADDS * ELSE * DOPBL2 = 6*MULTS + 2*ADDS * END IF * RETURN * * End of DOPBL2 * END geany-2.0/tests/ctags/bug1020715.c0000644000175000017500000000253514514252267013340 00000000000000/* Bugs item #1020715, was opened at 2004-09-01 22:42 Message generated for change (Tracker Item Submitted) made by Item Submitter You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=106556&aid=1020715&group_id=6556 Category: None Group: None Status: Open Resolution: None Priority: 5 Submitted By: Arne Georg Gleditsch (argggh) Assigned to: Nobody/Anonymous (nobody) Summary: Strange parsing of C code Initial Comment: Running ctags 5.5.4 like this /usr/local/bin/ctags --fields=+S --excmd=number -f - --c-types=+l /usr/src/source/2.6.6/drivers/scsi/aha152x.c | grep ^done returns a bogus entry for the function "done" on line 1745 with a wacky signature. The file aha152x.c is from Linux 2.6.6, but is appended for convenience. */ /* Date: 2007-08-14 01:00 Sender: elliotth Hide i don't really understand why the other lines in the test case were necessary to exercise the bug, but changing parseParens to call processAngleBracket instead of just skipToMatch("<>") fixes this bug. i've committed that since it causes no regressions. Date: 2007-08-14 00:34 Sender: elliotth Hide i've come up with a minimal test case, and committed it. it's pretty weird: */ void f() { done(a<<1); a->a; if (a->a) { } } /* change just about anything and the bizarre "done" tag goes away. you can't even switch from '->' to '.', which seems odd. */ geany-2.0/tests/ctags/objectivec_protocol.mm.tags0000644000175000017500000000015414514252267017200 00000000000000lockÌ128Í()ÎLockingÖ0 method: Locking :: lock() unlockÌ128Í()ÎLockingÖ0 method: Locking :: unlock() geany-2.0/tests/ctags/namelist.f0000644000175000017500000000020214514252267013627 00000000000000 PROGRAM main NAMELIST /namelist1/ n1a, n1b NAMELIST /namelist2/ n2a, n2b /namelist3/ n3a, n3b END geany-2.0/tests/ctags/bug849591.cpp.tags0000644000175000017500000000007714514252267014600 00000000000000FooÌ16Í()ÎMainClassÖ0Ïvoid function: void MainClass :: Foo() geany-2.0/tests/ctags/keyword_protected.cs.tags0000644000175000017500000000036614514252267016700 00000000000000MainÌ128Í()ÎMyDerivedCÖ0Ïpublic void method: public void MyDerivedC :: Main() MyClassÌ1Ö0 class: MyClass MyDerivedCÌ1Ö0 class: MyDerivedC xÌ8ÎMyClassÖ0Ïint field: int MyClass :: x yÌ8ÎMyClassÖ0Ïint field: int MyClass :: y geany-2.0/tests/ctags/simple.py.tags0000644000175000017500000000352714514252267014461 00000000000000ALLÌ16384Ö0 variable: ALL DATAÌ16384Ö0 variable: DATA INDENTÌ16384Ö0 variable: INDENT KEYÌ16384Ö0 variable: KEY TREEIDÌ16384Ö0 variable: TREEID VERSIONÌ16384Ö0 variable: VERSION __init__Ì128Í(self, filename, pathsep='', treegap=64)ÎoneÖ0 method: one :: __init__(self, filename, pathsep='', treegap=64) __private_function__Ì128Í(self, key, data)ÎoneÖ0 method: one :: __private_function__(self, key, data) _packÌ128Í(self, i, s)ÎoneÖ0 method: one :: _pack(self, i, s) _testÌ16Í(test, code, outcome, exception)Ö0 function: _test(test, code, outcome, exception) bsddbÌ32768Ö0 externvar: bsddb btopenÌ32768ÎbsddbÖ0 externvar: bsddb :: btopen deeply_nestedÌ1Î_test.ignored_function.more_nestingÖ0 class: _test.ignored_function.more_nesting :: deeply_nested even_moreÌ128Í()Î_test.ignored_function.more_nesting.deeply_nestedÖ0 method: _test.ignored_function.more_nesting.deeply_nested :: even_more() fooÌ16Í( x, y, z)Ö0 function: foo( x, y, z) ignored_functionÌ16Í()Î_testÖ0 function: _test :: ignored_function() more_nestingÌ16Í()Î_test.ignored_functionÖ0 function: _test.ignored_function :: more_nesting() oneÌ1Ö0 class: one onlyÌ128Í(arg)ÎtwoÖ0 method: two :: only(arg) public_functionÌ128Í(self, key)ÎoneÖ0 method: one :: public_function(self, key) so_is_thisÌ1ÎoneÖ0 class: one :: so_is_this thisÌ1Î_test.ignored_function.more_nesting.deeply_nested.even_moreÖ0 class: _test.ignored_function.more_nesting.deeply_nested.even_more :: this thisÌ128Î_test.ignored_function.more_nesting.deeply_nested.even_more.thisÖ0 method: _test.ignored_function.more_nesting.deeply_nested.even_more.this :: this this_is_ignoredÌ1Îone.public_functionÖ0 class: one.public_function :: this_is_ignored threeÌ1Ö0 class: three twoÌ1Ö0 class: two xÌ128Í(x)ÎoneÖ0 method: one :: x(x) yÌ16384ÎoneÖ0 variable: one :: y geany-2.0/tests/ctags/3526726.tex0000644000175000017500000037002514514252267013241 00000000000000% $Id$ %latex2html -info 0 -local_icons -show_section_numbers -link 2 -split +1 faq.tex \documentclass{article} \usepackage{html} \usepackage{graphicx} \usepackage{fancyhdr} \usepackage{makeidx} %% Margins \oddsidemargin 0in \evensidemargin 0in \textwidth 6.5in \topmargin 0in \textheight 8in \setlength{\parindent}{0in} \setlength{\parskip}{.5\baselineskip} \pagestyle{fancy} \lhead{ {\sc Snort FAQ} } \cfoot{ {\sc feed the pig}} \rhead{Page \thepage} \newcommand{\myref}[1]{(see FAQ \ref{#1})} \newcommand{\myquote}[1]{\begin{quote}#1\end{quote}} %\label{key} assign current counter value to key %\myref{key}{print value assigned to key} % To emphasise % {\em blah} % To bold % {\bf bold face } % The following characters are special characters and need to be backslashed % before use: % $ & % # _ { } % % To get a backslash, try $\backslash$ \makeindex \begin{document} \title{ The Snort FAQ } \author{ The Snort Core Team } \date{ } % Title Page \maketitle \newpage Suggestions for enhancements of this document are always welcome. Please email them to the \htmladdnormallink{Snort-Users}{mailto:snort-users@lists.sourceforge.net} mailing list. Many people have contributed to this FAQ: \begin{center} \begin{tabular}{llll} Marty Roesch & Fyodor Yarochkin & Dragos Ruiu & Jed Pickel\\ Max Vision & Michael Davis & Joe McAlerney & Joe Stewart\\ Erek Adams & Roman Danyliw & Christopher Cramer & Frank Knobbe\\ Phil Wood & Toby Kohlenberg & Ramin Alidousti & Jim Hankins\\ Dennis Hollingworth & Paul Howell & Stef Mit & Ofir Arkin\\ Jason Haar & Blake Frantz & Lars Norman S?ndergaard & Brent Erickson\\ Brian Caswell & Scot Wiedenfeld & Chris Green & Jeff Wirth\\ Edin Dizdarevic & Detmar Liesen & Don Ng & Matt Kettler\\ Joe Lyman & Jim Burwell & Jed Haile & Andrew Hutchinson\\ Jeff Nathan & Alberto Gonzalez & Jason Haar & Jeremy Hewlett \end{tabular} \end{center} If you do not see your name on this list and you have contributed to the faq, please email \htmladdnormallink{bugs@snort.org}{mailto:bugs@snort.org}. Dragos Ruiu: This version of this guide has been brought to you by the kind generosity and sponsorship of Wiley and Sons publishers whose support let myself, and other snort developers Jeff Nathan and Jed Haile take the time to work on this document and other tutorials for Snort due out in our upcoming book. (route++) \newpage \begin{latexonly} \tableofcontents \newpage \end{latexonly} \section{Background} \subsection{How do you pronounce the names of some of these guys who work on Snort?} For the record, `Roesch' is pronounced like `fresh' without the `f.' Additionally, `Ruiu' is pronounced like `screw you' without the `sc.' Jed's last name is like `pick-el,' not `pickle.' \subsection{Is Fyodor Yarochkin the same Fyodor who wrote nmap?} Nope. fyodor@insecure.org is the author of nmap, and he uses the same pseudonym as the other Snort Fyodor's real surname. Yeah, it messes up my mailbox too, but I think it's too late to change either of them. \subsection{Where do I get more help on Snort?} Check the website, \htmladdnormallink{http://www.snort.org/}{http://www.snort.org/}. Other good resources are available in the source distribution, including the \htmladdnormallink{Snort Users Manual}{http://www.snort.org/docs} and the USAGE file. There is also a excellent mailing list, snort-users. You can find info on how to signup at \htmladdnormallink{http://www.snort.org/community/mailing-lists/}{http://www.snort.org/community/mailing-lists}. You can also join \#snort on irc.freenode.net. \subsection{Where can I get more reading and courses about IDS?\label{courses}} All of the following offer courses on Intrusion Detection: \begin{itemize} \item \htmladdnormallink{SANS (http://www.sans.org)}{http://www.sans.org} \item \htmladdnormallink{Usenix (http://www.usenix.org/event/)}{http://www.usenix.org/event/} \item \htmladdnormallink{Networld/Interop (http://www.key3media.com/interop/)}{http://www.key3media.com/interop/} \item \htmladdnormallink{CanSecWest (http://www.cansecwest.com)}{http://www.cansecwest.com} \end{itemize} There are many good books on Intrusion Detection. Here are just a few: \begin{tabular}{|p{2in}|p{1.5in}|l|l|} \hline {\bf Title} & {\bf Author(s)} & {\bf Publisher} & {\bf ISBN}\\ \hline\hline Snort 2.1 Intrusion Detection, Second Edition & Brian Caswell, Jay Beale & 1931836043 \\ \hline Tao of Network Security Monitoring, The: Beyond Intrusion Detection & Richard Bejtlich & 0321246772 \\ \hline Intrusion Detection with Snort: Advanced IDS Techniques & Rafeeq Rehman & Prentice Hall & I0131407333\\ \hline Snort Intrusion Detection & Ryan Russell & Syngress Media & 1931836744 \\ \hline Snort Intrusion Detection & Jack Koziol & New Riders & 157870281X\\ \hline Network Intrusion Detection: An Analyst's Handbook & Stephen Northcutt & New Riders & 0735708681 \\ \hline Intrusion Signatures and Analysis & Stephen Northcutt & New Riders & 0735710635 \\ \hline TCP/IP Illustrated, Volume 1 The Protocols & W. Richard Stevens & Addison-Wesley & 0201633469 \\ \hline Intrusion Detection & Rebecca G. Bace & MacMillan Technical Publishing & 1578701856 \\ \hline The Tao of Network Security Monitoring: Beyond Intrusion Detection & Richard Bejtlich & Addison-Wesley & 0321246772 \\ \hline Snort 2.1 Intrusion Detection, Second Edition & Brian Caswell \& Jay Beale & Syngress Publishing & 1931836043 \\ \hline \end{tabular} \subsection{Does Snort handle IP defragmentation?} Yes, use {\tt preprocessor frag3}. \subsection{Does Snort perform TCP stream reassembly?} Yes, check out the stream4 preprocessor \myref{stream4} that does stateful analysis session login, TCP reassembly and much, much more. \subsection{Does Snort perform stateful protocol analysis?} Yes. Stream4 does this as well. See \myref{stream4}. \subsection{I'm on a switched network, can I still use Snort?} {\bf Short version:} Being able to sniff on a switched network depends on what type of switch is being used. If the switch can mirror traffic, then set the switch to mirror all traffic to the Snort machine's port. {\bf Extended version:} There are several ways of deploying NIDS in switched environments which all have their pros and cons. Which method applies to your needs depends on what kind of segments you want to monitor and on your budget. Here are the most common methods: \begin{enumerate} \item {\bf Switch mirror:} If the switch can mirror traffic, then set the switch to mirror all traffic to the Snort machine's port. \begin{itemize} \item Advantages: \begin{itemize} \item Simple method, works with most decent switches. \end{itemize} \item Drawbacks: \begin{itemize} \item If the switch is a fast Ethernet switch, you can mirror 100Mbit/s max. Since each switch port is capable of handling 100Mbit/s for each direction, the bandwidth per port sums up to 200Mbit/s, so the switch will not be able to mirror all packets at high network utilization. \item Some switches suffer from performance degradation through port mirroring. \end{itemize} \end{itemize} \item {\bf Hub:} Insert a hub in line, so you can simply tap all traffic. Works fine for home networks, will lose data due to collisions at loads greater than 50\%---so a 10Mbps hub should be fine for T1/E1, DSL or cablemodem. If you have a DS3 or greater, you should investigate taps. \begin{itemize} \item Advantages: \begin{itemize} \item Simple method \item No impact on switch performance and no config changes \item Low cost \end{itemize} \item Drawbacks: \begin{itemize} \item Loss of full-duplex capabilities \item Additional single point of failure \item Collision loss at above 50\% load levels \end{itemize} \end{itemize} \item {\bf Network taps:} Use network taps (e.g. Shomiti/Finisar [\htmladdnormallink{http://www.shomiti.com}{http://www.shomiti.com}] and Netoptics [\htmladdnormallink{http://www.netoptics.com}{http://www.netoptics.com}). You can find some rather good information in the papers by Jeff Nathan. You can find the papers at \htmladdnormallink{http://www.snort.org/docs/\#deploy}{http://www.snort.org/docs/\#deploy}. \begin{itemize} \item Advantages: \begin{itemize} \item No impact on switch performance and no special configuration \item Stealth---i.e., sending data back to the switch is disabled \item No single point of failure, ``fail-open'' if the tap power fails \end{itemize} \item Drawbacks: \begin{itemize} \item The datastream is split into TX and RX, so you need two NICs \item The two datastreams have to be recombined, i.e. merged, if you don't want to lose the capability of doing stateful analysis. This can be done by using channel bonding. Information can be found at \htmladdnormallink{http://sourceforge.net/projects/bonding}{http://sourceforge.net/projects/bonding}. \item Cost \end{itemize} \end{itemize} \item {\bf Throw money at it:} Tap switch ports (using the forementioned network taps) but only tap all incoming packets (RX lines of the switch ports), connecting those tap ports to a dedicated gigabit switch, which is capable of mirroring up to ten RX taplines to one single dedicated gigabit port, which is connected to a gigabit IDS machine. \begin{itemize} \item Advantages: \begin{itemize} \item Maximum coverage (i.e. monitor all switchports) \item No performance degradation or re-configuration of the switch \end{itemize} \item Drawbacks: \begin{itemize} \item Mucho \$\$\$ \end{itemize} \end{itemize} \end{enumerate} \subsection{Is Snort vulnerable to IDS noise generators like ``Stick'' and ``Snot''?} It is now possible to defeat these kinds of noise generators with the stream4 preprocessor (see \myref{stream4}). Even without the stream4 preprocessor enabled, Snort will weather the alert storm without falling over or losing a lot of alerts due to its highly optimized nature. Using tools that generate huge amounts of alerts will warn a good analyst that someone is trying to sneak by their defenses. \subsection{Can Snort be evaded by the use of polymorphic mutators on shellcode?} Yes, and this could defeat some of the NOP sled detection signatures, but the ordinary exploit rules should not be affected by this kind of obfuscation. The fnord preprocessor attempts to detect polymorphic shellcode attempts. \subsection{Does Snort log the full packets when it generates alerts? } Yes, the packets should be in the directory that has the same IP address as the source host of the packet which generated the alert. If you are using binary logging, there will be a packet capture file (.pcap) in the logging directory instead. \section{Getting Started} \subsection{Where do I find binary packages for BlueHat BSD-Linux-RT?} Repeat after me: \begin{verbatim} Go to http://www.snort.org/snort-downloads Click the link for the tar.gz tar zxvf snort-.tar.gz cd ./configure make su make install mkdir /var/log/snort cd etc vi snort.conf snort -D -c snort.conf exit \end{verbatim} ...and if you want to use our binary package uninstaller :-): \begin{verbatim} cd ; make uninstall \end{verbatim} And if you must, you can find some binaries at \htmladdnormallink{http://www.snort.org/snort-downloads}{http://www.snort.org/snort-downloads}. You can also find Snort in most BSD ports' trees. \subsection{How do I run Snort?} Run Snort in sniffer mode and make sure it can see the packets. \begin{verbatim}snort -dv\end{verbatim} Then run it with the HOME\_NET set appropriately for the network you're defending in your rules file. A default rules file comes with the snort distribution and is called ``snort.conf'' You can run this basic ruleset with the following command line: \begin{verbatim}snort -A full -c snort.conf\end{verbatim} If it's all set right, make sure the interface is in promiscuous mode by running the command from another window: \begin{verbatim}ifconfig -a\end{verbatim} The output from ifconfig should show if the interface is in promiscuous mode. If it's not, there should be a way to set it manually. Note that the default output mode (-A full) of Snort should not be used except in very controlled environments. It is the slowest way to run Snort and presents several hard to recover from problems with inode creation on filesystems. For people doing real IDS work, use something like (-A fast -b) to combine fast alert mode with tcpdump binary log files or use the unified format coupled with Barnyard. \subsection{Where are my log files located? What are they named?} The default location for logs is /var/log/snort. If snort is started with ``-l $<$directory$>$'', then the logs will be located in the directory specified. In the past, running Snort in daemon mode (-D) produced a file named ``snort.alert.'' For consistency's sake, this has been changed. Running Snort in both standard or daemon modes (-D) will produce a file named ``alert.'' Note the log file naming convention changed between 1.8 and 1.9. That funny alphanumeric soup at the end of the new names is a UNIX timestamp. This helps avoid file conflicts. \subsection{Why does Snort complain about /var/log/snort?} It requires this directory to log alerts to it. Try running the command: \begin{verbatim} mkdir -p /var/log/snort \end{verbatim} Make sure the logging directory is owned by the user Snort is running as. \subsection{Where's a good place to physically put a Snort sensor?} This is going to be heavily influenced by your organizations policy, and what you want to detect. One way of looking at it is determining if you want to place it inside or outside your firewall. Placing an IDS outside of your firewall will allow you monitor all attacks directed at your network, regardless of whether or not they are stopped at the firewall. This almost certainly means that the IDS will pick up on more events than an IDS inside the firewall, and hence more logs will be generated. Place an IDS inside your firewall if you are only interested in monitoring traffic that your firewall let pass. If resources permit, it may be best to place one IDS outside and one IDS inside of your firewall. This way you can watch for everything directed at your network, and anything that made it's way in. ADDENDA AD NAUSEUM Note: So this one still gets a lot of traffic even though it's in the FAQ. Erek Adams has noted this comprehensive and authoritative discussion of this perpetual discussion item---mildly edited, also see faq question about switches hubs and taps -dr If your router/switch can do port mirroring, then just connecting a network IDS to it would be fine. Or else a hub could be another option. Most network IDSes can have a NIC that acts as a passive sniffer anyway. As to where to place the sensor. I would go for both, one to monitor the external, one for the internal. I work in a distributor for security products, so over instrumentation is fun :) And in any case, if the traffic does not pass by the Sensor it will not get monitored. So some people deploy IDS on their internal segments too, I believe. {\bf In ``front'' of the firewall(s):} Pro: Higher state of alert you know what attacks you are facing. Con: Wall to Wall of data, boring? If your firewall has NAT turned on, tracking the sources originating from your internal network is difficult. {\bf ``Behind'' the firewall(s):} Pro: Only what gets through the firewall gets monitored? Less load on the IDS analyst. You get to see what hosts are sending traffic to the internet. Con: Less idea of the state of the environment, false sense of safety. {\bf Where should IDS be placed relative to firewalls? Explore the pros and cons of placing IDS inside or outside firewall. What are the drawbacks of each?} \begin{itemize} \item {\bf MARCUS RANUM from NFR Security:} "I'd put mine inside. Why should I care if someone is attacking the outside of my firewall? I care only if they succeed, which my IDS on the inside would ideally detect. Placing the IDS on the outside is going to quickly lull the administrator into complacency. I used to have a highly instrumented firewall that alerted me whenever someone attacked it. Two weeks later I was deleting its alert messages without reading them. Another important factor arguing for putting it inside is that not all intrusions come from the outside or the firewall. An IDS on the inside might detect new network links appearing, or attackers that got in via another avenue such as a dial-in bank.'' \item {\bf CURRY from IBM:} ``The IDS should be placed where it will be able to see as much of the network traffic you're concerned about as possible. For example, if you're concerned about attacks from the Internet, it makes the most sense to put the IDS outside the firewall. the most sense to put the IDS outside the firewall. This gives it an ``unobstructed'' view of everything that's coming in. If you put the IDS inside the firewall, then you're not seeing all the traffic the bad guys are sending at you, and this may impact your ability to detect intrusions.'' \item {\bf SUTTERFIELD from Wheel Group:} ``IDS ideally plays an important role both inside and outside a firewall. Outside a firewall, IDS watches legitimate traffic going to public machines such as e-mail and Web servers. More importantly IDS outside a firewall will see traffic that would typically be blocked by a firewall and would remain undetected by an internal system. This is especially important in detecting network sweeping which can be a first indication of attack. External systems will also give you the benefit of monitoring those services that firewalls determine are legitimate. Putting an IDS inside the firewall offers the added benefit of being able to watch traffic internal to the protected network. This adds an important element of protection against insider threats. The major drawback of IDS inside a firewall is that it cannot see a good deal of important traffic coming from untrusted networks and may fail to alert on obvious signals of an impending attack.'' \item {\bf CHRIS KLAUS from ISS:} ``Outside the firewall is almost always a good idea---it protects the DMZ devices from attack and dedicates an additional processor to protecting the internal network. Just inside the firewall is also useful-it detects attempts to exploit the tunnels that exist through the firewall and provides an excellent source of data for how well your firewall is working. Throughout your intranet may be the best place for IDS deployment, however. Everyone agrees that attacks aren't the only things we're worried about-there's internal mischief, fraud, espionage, theft, and general network misuse. Intrusion detection systems are just as effective inside the network as outside, especially if they're unobtrusive and easy to deploy.'' \item {\bf GENE SPAFFORD:} ``The IDS must be inside any firewalls to be able to detect insider abuse and certain kinds of attacks through the firewall. IDS outside the firewall may be useful if you want to monitor attacks on the firewall, and to sample traffic that the firewall doesn't let through. However, a true IDS system is likely to be wasted there unless you have some follow-through on what you see.'' \vspace{10pt} Bottom Line: {\bf DRAGOS RUIU:} ``Just pick a spot you're likely to look at the logs for. :-)'' \end{itemize} \subsection{Libpcap complains about permissions problems, what's going on?} You are not running Snort as root or your kernel is not configured correctly. \subsection{ I've got RedHat and ....} Check your version of libpcap. If it's not $>=$ 0.5, you should update. \subsection{Where do I get the latest version of libpcap? } You can find the most current version at: \htmladdnormallink{http://www.tcpdump.org}{http://www.tcpdump.org/} You might also want to have a look at Phil Wood's patches to libpcap for Linux: \htmladdnormallink{http://public.lanl.gov/cpw/}{http://public.lanl.gov/cpw/} \subsection{Where do I get the latest version of Winpcap?} \htmladdnormallink{http://winpcap.polito.it/}{http://winpcap.polito.it/} \subsection{What version of Winpcap do I need?\label{winpcap}} It depends. If you only have one processor, you can use the most current version (3.x). If you have a SMP box, you'll have to use either an older version ($<$ 2.3) or the 3.x version plus a patch from \htmladdnormallink{http://www.ntop.org/winpcap.html}{http://www.ntop.org/winpcap.html}. \subsection{Why does building Snort complain about missing references? } You must configure libpcap with the --install-incl option. (On Red Hat, install the libpcap-devel rpm.) \subsection{Why does building snort fail with errors about yylex and lex\_init? } You need the lex and yacc tools or their gnu equivalents flex and bison installed. \subsection{I want to build a Snort box. Will this $<$Insert list of hardware$>$ handle $<$this much$>$ traffic? } That depends. Lower the number of rules is a standard performance increase. Disable rules that you don't need or care about. There have been many discussions on 'tweaking performance' with lots of 'I handle XX mb with a \_\_\_ machine setup.' being said. Look at some of the discussions on the snort-users mailing lists. Here is an oft quoted bit on the subject from Marty: ``Hardware/OS recommendations'' Ok, here are the guidelines and some parameters. Intrusion detection is turning into one of the most high performance production computing fields that is in wide deployment today. If you think about the requirements of a NIDS sensor and the constraints that they are required to operate within, you'll probably start to realize that it's not too hard to find the performance wall with a NIDS these days. The things a NIDS needs are: \begin{enumerate} \item MIPS (Fast CPU) \item RAM (More is *always* better) \item I/O (Wide, fast busses and high performance NIC) \item AODS (Acres Of Disk Space) \end{enumerate} A NIDS also needs to be pretty quick internally at doing its job. Snort's seen better days in that regard (when 1.5 came out the architecture was a lot cleaner) but it's still considered to be one of the performance leaders available. As for OS selection, use what you like. When we implement Data Acquisition Plugin's in Snort 2.0 this may become more of a factor, but for now I'm hearing about a lot of people seeing a lot of success using Snort on Solaris, Linux, *BSD and Windows 2000. Personally, I develop Snort on FreeBSD and Sourcefire uses OpenBSD for our sensor appliance OS, but I've been hearing some good things about the RedHat Turbo Packet interface (which would require mods for Snort to use, not to mention my general objection to RedHat's breaking stuff all the time). (ed note: take a drink, see FAQ 7.2 -dr) \subsection{What are CIDR netmasks? } (Excerpt from url: \htmladdnormallink{http://public.pacbell.net/dedicated/cidr.html}{http://public.pacbell.net/dedicated/cidr.html}) CIDR is a new addressing scheme for the Internet which allows for more i efficient allocation of IP addresses than the old Class A, B, and C address scheme. \begin{center} \begin{tabular}{llr} {\bf CIDR Block} & {\bf Equivalent Class C} & {\bf Addresses}\\ /27 & 1/8th of a Class C & 32 hosts \\ /26 & 1/4th of a Class C & 64 hosts\\ /25 & 1/2 of a Class C & 128 hosts\\ /24 & 1 Class C & 256 hosts\\ /23 & 2 Class C & 512 hosts\\ /22 & 4 Class C & 1,024 hosts\\ /21 & 8 Class C & 2,048 hosts\\ /20 & 16 Class C & 4,096 hosts\\ /19 & 32 Class C & 8,192 hosts\\ /18 & 64 Class C & 16,384 hosts\\ /17 & 128 Class C & 32,768 hosts\\ /16 & 256 Class C & 65,536 hosts \\ /15 & 512 Class C & 131,072 hosts\\ /14 & 1,024 Class C & 262,144 hosts\\ /13 & 2,048 Class C & 524,288 hosts\\ \end{tabular} \end{center} For more detailed technical information on CIDR, check out the following RFCs: \begin{itemize} \item RFC 1517: Applicability Statement for the Implementation of CIDR \item RFC 1518: An Architecture for IP Address Allocation with CIDR \item RFC 1519: CIDR: An Address Assignment and Aggregation Strategy \item RFC 1520: Exchanging Routing Information Across Provider Boundaries in the CIDR Environment \end{itemize} RFCs are available at \htmladdnormallink{http://www.rfc-editor.org/rfcsearch.html}{http://www.rfc-editor.org/rfcsearch.html} \subsection{What is the use of the ``-r'' switch to read tcpdump files? } Used in conjunction with a Snort rules file, the tcpdump data can be analyzed for hostile content, port scans, or anything else Snort can be used to detect. Snort can also display the packets in a decoded format, which many people find is easier to read than native tcpdump output. \section{Configuring Snort} \subsection{How do I setup snort on a `stealth' interface? }\label{stealth} In *BSD and Linux: \begin{verbatim}ifconfig eth1 up\end{verbatim} Solaris: \begin{verbatim}ifconfig eth1 plumb ifconfig eth1 up\end{verbatim} For NT/W2K/XP users, try the following: NOTE: You are at your own risk if you follow these instructions. Editing your registry is DANGEROUS and should be done with extreme caution. Follow these steps at your OWN risk. \begin{enumerate} \item Get your device's hex value. ('snort -W' works for this) \item open Regedt32 \item Navigate to: HKEY\_LOCAL\_MACHINE$\backslash$SYSTEM$\backslash$CurrentControlSet$\backslash$Services$\backslash$Tcpip$\backslash$Parameters$\backslash$\linebreak Interfaces$\backslash$\{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX\} \item Select the network card you wish to setup as the monitoring interface (this will be the \{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX\} value). \item Set IPAddress:REG\_MULTI\_SZ: to null (Double click on the string, delete data in the Multi-String Editor, then click OK) \item Set SubnetMask:REG\_MULTI\_SZ: to null (Double click on the string, delete data in the Multi-String Editor, then click OK) \item Set DefaultGateway:REG\_MULTI\_SZ: to null (Double click on the string, delete data in the Multi-String Editor, then click OK) \item Close the Registry Editor, your changes will be saved automatically. \item In a command prompt, run 'ipconfig' to verify the interface does not have an IP bound to it. \end{enumerate} If you do not receive an IP address listing from the interface you modified, you are good to go. To run snort with the specified interface, use the -i flag such as 'snort -v -d -p -i1' \subsection{How do I setup a receive-only ethernet cable?} Use an ethernet tap, or build your own 'receive-only' ethernet cable. Anyway, here is the cable I use: \begin{verbatim} LAN Sniffer 1 -----\ /-- 1 2 ---\ | \-- 2 3 ---+-*------ 3 4 - | - 4 5 - | - 5 6 ---*-------- 6 7 - - 7 8 - - 8 \end{verbatim} Basically, 1 and 2 on the sniffer side are connected, 3 and 6 straight through to the LAN. 1 and 2 on the LAN side connect to 3 and 6 respectively. This fakes a link on both ends but only allows traffic from the LAN to the sniffer. It also causes the 'incoming' traffic to be sent back to the LAN, so this cable only works well on a hub. You can use it on a switch but you will get ...err... interesting results. Since the switch receives the packets back in on the port it sent them out, the MAC table gets confused and after a short while devices start to drop off the switch. Works like a charm on a hub though. Another method which uses a capacitor and should work on 100mbs links: \htmladdnormallink{http://www.geocities.com/samngms/sniffing\_cable}{http://www.geocities.com/samngms/sniffing_cable} And another: The UTP Y-Cable specified by Joe Lyman: A less noisy option: it involves a couple of cat 5 cables and a single speed hub. The idea is to use the rcv cables for the wire going to the sniffer box and use the xmit cables from another hub port. This will give you a link light and allow your sniffer to rcv only. Cannot xmit because the xmit cables are not connected. This has been successfully used on netgear single speed hubs. It wont work on dual speed hubs due to the negotiation of speed. Pin outs. They are reversed in the picture in order to prevent lines from crossing, and I only included the pins used. \begin{verbatim} * []HUB PORT 1 HUB PORT 2 ----- ----- x x r r r r x x 6 3 2 1 1 2 3 6 | | | | | | | | | ----------- | | | ------------- | | | | | | | | 6 3 2 1 r r x x ---- SNIFFER x = xmit r = rcv \end{verbatim} You could make it a single cable by adding a battery to simulate the voltage from the xmit cables on the nic, but batteries die. It's not recommended to cut the transmit side, shunt it to ground (pin 2). Some OS's will disable the interface if PIN 1 does not indicate a completed circuit. \subsection{What are HOME\_NET and EXTERNAL\_NET?} HOME\_NET and EXTERNAL\_NET are standard variable names that all of the Snort.org rules use. HOME\_NET refers to the network(s) that you want to protect, where EXTERNAL\_NET is the network(s) that you think attacks would come from. \subsection{My network spans multiple subnets. How do I define HOME\_NET?} Snort 1.7 supports IP lists. You can assign a number of addresses to a single variable. For example: \begin{verbatim}var HOME_NET [10.1.1.0/24,192.168.1.0/24]\end{verbatim} NOTE: Not all preprocessors support IP lists at this time. Unless otherwise stated, assume that any preprocessor using an IP list variable will use the first value as the HOME\_NET. The portscan preprocessor is an example. To catch all detectable portscans, pass 0.0.0.0/0 in as the first parameter. \begin{verbatim}preprocessor portscan: 0.0.0.0/0 5 3 portscan.log\end{verbatim} Use the portscan-ignorehosts preprocessor to fine tune and ignore traffic from noisy, trusted machines. \subsection{How do I set EXTERNAL\_NET?} Many people set EXTERNAL\_NET to ``any''. \begin{verbatim} var EXTERNAL_NET any \end{verbatim} By setting it to ``any'' Snort will alert you on any traffic matching a rule coming into or leaving your network. To cut down on the work that Snort has to do, many people set it to ``not HOME\_NET.'' \begin{verbatim} var EXTERNAL_NET !$HOME_NET \end{verbatim} This tells Snort to define EXTERNAL\_NET as everything except HOME\_NET. For most people this is the best thing to set it to. \subsection{How can I run Snort on multiple interfaces simultaneously?} LINUX: If you aren't running snort on linux 2.1.x/2.2.x kernel (with LPF available) the only way is to run multiple instances of snort, one instance per interface (with the -i option specifying the interface). However for linux 2.1.x/2.2.x and higher you can use libpcap library with S. Krahmer's patch which allows you to specify 'any' as interface name. In this case snort will be able to process traffic coming to all interfaces. *BSD: Use the ``bridge'' interface to combine your nics into a logical interface (bridge0). \subsection{My IP address is assigned dynamically to my interface, can I use Snort with it?} Yes. With Snort 1.7 and later, $<$interface$>$\_ADDRESS variable is available. The value of this variable will be always set to IP address/Netmask of the interface which you run snort at. if interface goes down and up again (and an IP address is reassigned) you will have to restart snort. For earlier versions of snort numerous scripts to achieve the same result are available. \subsection{I have one network card and two aliases, how can I force Snort to ``listen'' on both addresses?} If you're using at least version 1.7, you can specify an IP list like this: \begin{verbatim}var HOME_NET [ 192.168.10.0/24, 10.1.1.1/16 ]\end{verbatim} If you're using something older (version 1.6.3-patch2 or whatever) you can re-specify the HOME\_NET variable multiple times like this (for example): \begin{verbatim} var HOME_NET 10.1.1.0/24 include misc.rules var HOME_NET 192.168.1.0/24 include misc.rules \end{verbatim} \subsection{How do I ignore traffic coming from a particular host or hosts?} There are two basic ways to ignore traffic from a host: \begin{itemize} \item Pass Rules \item BPF Filters \end{itemize} Details: \begin{enumerate} \item Pass Rules: \begin{itemize} \item Advantages: \begin{itemize} \item Gives you rule based control over the packets. \item Puts all your changes into 'one place'-snort.conf. \end{itemize} \item Disadvantages: \begin{itemize} \item Reverses the Rule order, can cause some headaches in tracking down problems. \item One poorly written pass rule can 'blind' your whole network. \item The more specific the pass rule is, the more CPU snort needs to process it which may be important on loaded nets. \end{itemize} \item Example: For example to ignore ALL ICMP traffic from host using a pass rule: \begin{verbatim} pass icmp any -> $HOME_NET any \end{verbatim} \end{itemize} \item BPF Filters: \begin{itemize} \item Advantages: \begin{itemize} \item Drops the packet at the BPF interface, which saves on processing. \item Speeds up Snort since it 'never sees' those packets. \end{itemize} \item Disadvantages: \begin{itemize} \item Poorly constructed filters can 'blind-side' you. \end{itemize} \item Example: \begin{itemize} \item To ignore all traffic from 192.168.0.1: \begin{verbatim} snort not host 192.168.0.1 \end{verbatim} \item To ignore all ICMP ECHO-REQUESTS (pings) and ICMP-ECHO REPLY's (ping reply) from host $<$foo$>$: \begin{verbatim} snort ``not ( (icmp[0] = 8 or icmp[0] = 0) and host )'' \end{verbatim} \end{itemize} \end{itemize} \end{enumerate} \subsection{How do I get Snort to log the packet payload as well as the header?} It depends on how your Snort configuration logs. If it logs in binary format, you'll have to process the binary log in order to get cleartext. You also might have ``-A $<$foo$>$'' on the command line. Command line options always take override the .conf file. \subsection{Why are there no subdirectories under /var/log/snort for IP addresses?} It depends on how your snort configuration logs. If it logs in binary format, you'll have to process the binary log in order to get cleartext. \subsection{How do you get Snort to ignore some traffic?} Snort can be made to ignore traffic in a number of different ways: \begin{enumerate} \item Specify bpf filters on the command line the tcpdump man page has a description of bpf filters. \item Use a pass rule \item The portscan preprocessor has it's own special exclusion list with the portscan-ignorehosts.rules file directive \end{enumerate} \subsection{Why does the portscan plugin log ``stealth'' packets even though the host is in the portscan-ignorehosts list? } These types of tcp packets are inherently suspicious, no matter where they are coming from. The portscan detector was built with the assumption that {\em stealth} packets should be reported, even from hosts which are not monitored for portscanning. An option to ignore ``stealth'' packets may be added in the future. \subsection{What the heck is a ``Stealth scan''?} A Stealth scan can refer to more than one type of scan. \begin{itemize} \item {\bf Half-Open or SYN scan:} Instead of completing the full TCP three-way-handshake a full connection is not made. A SYN packet is sent to the system and if a SYN/ACK packet is received it is assumed that the port on the system is active. In that case a RST/ACK will be sent which will determined the listening state the system is in. If a RST/ACK packet is received, it is assumed that the port on the system is not active. \item {\bf FIN scan:} According to RFC 793 a system should send back an RST for all TCP ports closed when they receive a FIN packet for a specific port. \item {\bf XMAS tree scan:} According to RFC 793 a system should send back an RST for all TCP ports closed when they receive a FIN/URG/PUSH packet for a specific port. \item {\bf NULL scan:} According to RFC 793 a system should send back an RST for all TCP ports closed when they receive a packet without any specified IP flags for a specific port. \item {\bf Slow scan:} Any of the above scans could be used as a slow scan. A slow scan is when the attacker sends packets at a {\bf very} slow rate. Sometimes these scans can be conducted over hours, days, or weeks. The idea is since they are so slow, the victim's security measures won't ``notice'' the scan. \end{itemize} \subsection{What the heck is a SYNFIN scan?} SYNFIN scans got their name because there are both the SYN and FIN flags set. \subsection{Which takes precedence, commandline or rule file ?} The command line always gets precedence over the rules file. If people want to try stuff out quickly without having to manually edit the rules file, they should be able to override many things from the command line. \subsection{How does rule ordering work?} {\bf For $=>$ 2.0:} Please see the documents on v2.0 at: \htmladdnormallink{http://www.snort.org/docs/development-papers/}{http://www.snort.org/docs/development-papers/}. {\bf For $<=$ 1.9.X:} Marty has answered this many times on the snort-users mailing list. Here is an excerpt from a post on Thu, 22 Feb 2001 00:31:53 -0500, titled {\em ``Re: [Snort-users] order of evaluation of rules.''} Currently, the data structures that store Snort rule data are the RuleTreeNodes (RTN) and the OptTreeNodes (OTN). These data structs are stored in a two dimensinal linked list structure with the RTNs forming the top row of the ``Array'' and the OTNs forming the columns under the RTNs. Here's an ASCII illustration from the infamous ``lisapaper'': \begin{verbatim} RTN RTN RTN -------------- -------------- ----- | Chain Header | | Chain Header | | Chai | | | | | | Src IP | | Src IP | | Src | Dst IP |----->| Dst IP |----->| Dst ..... | Src Port | | Src Port | | Src | Dst Port | | Dst Port | | Dst | | | | | -------------- -------------- ----- | | | | | | OTN \|/ OTN \|/ -------V------ --------V------- | Chain Option | | Chain Option | | | | : | | Content | : | TCP Flags | : | ICMP Data | | Payload Size | | etc. | | | --------------- | | | OTN \|/ -------V------ | Chain Option | | | | Content | | TCP Flags | | ICMP data | | Payload Size | | etc. | | | -------------- | | \end{verbatim} Rules with similar rule headers (i.e. all the CGI rules, the old stealth port scan detection rules, most of the rules that focus on any single service, etc) are grouped under a single RTN for the sake of efficiency and the applicable OTNs are hung below them. For instance, if you have three rules like this: \begin{verbatim} alert tcp any any -> $HOME 80 (content: "foo"; msg: "foo";) alert tcp any any -> $HOME 80 (content: "bar"; msg: "bar";) alert tcp any any -> $HOME 80 (content: "baz"; msg: "baz";) \end{verbatim} They all get grouped under the same RTN and the OTNs are ``hung'' beneath them like this: \begin{verbatim} RTN -------------------- | SIP: any | | SP: any | | DIP: $HOME | | DP: 80 | -------------------- | | OTN \|/ ---------v---------- | content: foo | | msg: foo | --------------------- | | OTN \|/ ---------v---------- | content: bar | | msg: bar | --------------------- | | OTN \|/ ---------v---------- | content: baz | | msg: baz | --------------------- \end{verbatim} This is an efficient way to do things because we only need to check the data in the RTN once with this method. There is actually another dimension to this array: the function pointer list. Each node in the ``array'' has a linked list of function pointers attached to it. The functions in this list are the tests that need to be done to determine whether the data in the current packet matches the current rule node's information. Having this function pointer list gives us great efficiency and flexibility: we don't need to perform tests for things the current rule doesn't contain (e.g., ``any'' ports/IPs, packet content on non-content rules, etc). It also allows us to analyze the packet with any function without having to make major modifications to the whole program (which was the case in versions prior to version 1.5). There are a couple of implications of this architecture. For the sake of this discussion on rules ordering, the one we're interested in is that rule order is tricky to figure out. For instance: \begin{verbatim} alert tcp any any -> $HOME 80 (content: "foo"; msg: "foo";) alert tcp any any -> $HOME 1:1024 (flags: S; msg: "example";) alert tcp any any -> $HOME 80 (flags: S; msg: "Port 80 SYN!";) alert tcp any any -> $HOME 80 (content: "baz"; msg: "baz";) \end{verbatim} gets built like this: \begin{verbatim} RTN RTN -------------------- -------------------- | SIP: any | | SIP: any | | SP: any |-------->| SP: any | | DIP: \$HOME | | DIP: \$HOME | | DP: 80 | | DP: 1-1024 | -------------------- -------------------- | | | | OTN \|/ \|/ ---------v---------- ---------v---------- | content: foo | | flags: S | | msg: foo | | msg: example | -------------------- -------------------- | | OTN \|/ ---------v---------- | flags: S | | msg: Port 80 SYN! | -------------------- | | OTN \|/ ---------v---------- | content: baz | | msg: baz | -------------------- \end{verbatim} Note that all three of the port 80 rules will be checked before the ``1:1024'' rule due to the order in which the applicable RTN has been created. This is because the rules parser builds the first chain header for port 80 traffic and sticks it on the rules list, then on the next rule it sees that a new chain header is required, so it gets built and put in place. In this case you would intuitively expect to get the ``example'' message and never see the ``Port 80 SYN!,'' but the opposite is true. \subsection{How do I configure stream4?} \label{stream4} Stream4 is an entirely new preprocessor that preforms two functions: \begin{itemize} \item Stateful inspection of TCP sessions \item TCP stream reassembly \end{itemize} Marty implemented stream4 out of the desire to have more robust stream reassembly capabilities and the desire to defeat the latest ``stateless attacks'' that have been coming out against Snort (c.f. stick and snot). Stream4 is written with the intent to let Snort be able to handle performing stream reassembly for ``enterprise class'' users, people who need to track and reassemble more than 256 streams simultaneously. Marty optimized the code fairly extensively to be robust, stable, and fast. The testing and calculations I've performed lead me to be fairly confident that stream4 can provide full stream reassembly for several thousand simultaneous connections and stateful inspection for upwards of 64,000 simultaneous sessions. Stream4 is a large and complex piece of code (almost 2000 lines) and there are a lot of options associated with its runtime configuration, so I'll go over them here. \begin{verbatim} preprocessor stream4: [noinspect], [keepstats], [timeout ], [memcap] \end{verbatim} stream4\_reassemble defaults: \begin{verbatim} Reassemble client: ACTIVE Reassemble server: INACTIVE Reassemble ports: 21 23 25 53 80 143 110 111 513 Reassembly alerts: ACTIVE \end{verbatim} \subsection{Where does one obtain new/modifed rules? How do you merge them in?} New rules can be downloaded via CVS \myref{cvs} or, alternatively, may be found at www.snort.org. There is a mailing list dedicated to Snort rules, called snort-sigs hosted at Sourceforge. There are some scripts/programs to help you with rule management: \begin{itemize} \item oinkmaster: A simple Perl script to update the ruleset for you. \htmladdnormallink{http://www.algonet.se/~nitzer/oinkmaster/}{http://www.algonet.se/~nitzer/oinkmaster/} \item IDS Policy Manager: A win32 application that updates the ruleset using a GUI, then uploads your rulesets via scp. \htmladdnormallink{http://www.activeworx.com/idspm}{http://www.activeworx.com/idspm} \item snortpp: a program to merge multiple files into one master file sorted by SID. \htmladdnormallink{http://dragos.com/snortpp.tgz}{http://dragos.com/snortpp.tgz} \end{itemize} There is also this script that might be useful: \begin{verbatim} * []#!/bin/sh ########################################################################### #### # # Das Skript zum Herunterladen und installieren neuer IDS-Signaturen. # ########################################################################### #### MAILTO="admin@mydomain.de" MACHINE="machine1" #set -x SIGS_URL1="http://www.snort.org/dl/signatures/snortrules-stable.tar.gz" MD5_URL1="http://www.snort.org/dl/signatures/snortrules-stable.tar.gz.md5" WGET="/usr/bin/wget" #WGET_PARAMS="-N" WGET_PARAMS="-t 3 -T 5 -N -a /etc/snort/snort.log -P /etc/snort" # Wget parameters: # # -t : Retries (here 3) # -N : Get the file only if newer # -a : Append the log messages to the specified file # -P : Save the file to the specified directory # -T : Timeout ECHO="/bin/echo" TAR="/bin/tar" KILL="/bin/kill" PIDOF="/sbin/pidof" SNORT="/usr/local/bin/snort" SNORTUSER="snort" SNORTGROUP="snort" KILLSIG="SIGUSR1" SERVICE="/sbin/service" # Where is the Snort configuration dir: RULESPATH="/etc/snort/snortrules" SNORTCFGPATH="/etc/snort" MD5SUM="/usr/bin/md5sum" MD5SUM_PARAMS="" # The list of sensor interfacec divided by blanks IFACES="eth0" ########################################################################### #### # F U N C T I O N S # ########################################################################### #### ########################################################################### #### # Die Funktion, die Snort fuer alle def. Interfaces auf dem System startet # # # # Um sie zu erweitern muss man zwei Dinge tun: # # 1. Die Parameterliste von Interfaces erweitern # # 2. Das Konfigurationsfile unter /etc/snort/snort.conf_ethX anlegen # # # ########################################################################### #### restartsnort() { # Restarting Snort for all interfaces for i in $IFACES; do "$ECHO" "Setting up Snort for interface "$i"" $ECHO "Restarting Snort..." #/usr/bin/killall snort if [ -f /var/run/snort_"$i".pid ] then PID=$("$PIDOF" "$SNORT") if [ -z "$PID" ] then "$SERVICE" snort restart else #`cat /var/run/snort_"$i".pid` "$ECHO" "Restarting Snort running with PID "$PID" and reloading the rules..." "$KILL" -s "$KILLSIG" "$PID" fi else "$ECHO" "No PID file for interface "$i" found under /var/ run" fi "$ECHO" "Starting Snort" "$SNORT" -a -b -c "$SNORTCFGPATH""/snort.conf_""$i" -I -D -v -i $i -u "$SNORTUSER" -g "$SNORTGROUP" PID=`cat /var/run/snort_"$i".pid` "$ECHO" "Snort running now with PID "$PID"" done } ########################################################################### #### # Die Funktion zum ueberpruefen, ob und wie Snort auf dem System laeuft # ########################################################################### #### checksnort() { SNORTS=$("$PIDOF" "$SNORT" | wc -w | awk '{print $1}') SNORT_PIDS=$(/usr/bin/find /var/run -name snort\_eth[0-9]\.pid -ls | wc -l | awk '{print $1}') "$ECHO" "Snort instances counted: $SNORTS" "$ECHO" "Snort PID files found: $SNORT_PIDS" # 1. Fall: Snort laeuft nicht oder PID-File nicht da: if [ "$SNORTS" = "0" -o "$SNORT_PIDS" = "0" ] then "$ECHO" "Snort seems to be down or no PID file there..." "$ECHO" "Restarting Snort for all Interfaces..." "$SERVICE" snort restart fi # 2. Fall: Anzahl der Instanzen ungleich der Anzahl der PID-Files if [ "$SNORTS" -gt "$SNORT_PIDS" ] then "$ECHO" "More Snort instances than found PID files..." "$ECHO" "Something is wrong outthere..." "$ECHO" "Stopping all Snort processes..." # /usr/bin/killall -9 snort "$SERVICE" snort stop "$ECHO" "Hold on... Restarting Snort now..." "$SERVICE" snort restart fi # 3. Fall: Anzahl der Instanzen stimmt mit der Anzahl der PID-files ueberein } ########################################################################### #### ########################################################################### #### getrules() { # Get the rules, since we know that they are newer... $WGET $WGET_PARAMS $SIGS_URL1 $WGET $WGET_PARAMS $MD5_URL1 "$ECHO" "Readout the checksum..." # MD5-Summe auslesen if [ -f /etc/snort/snortrules-stable.tar.gz.md5 ] then MD5SUM1=`grep MD5 \ /etc/snort/snortrules-stable.tar.gz.md5|awk '{print $4}'` else "$ECHO" "Error! No MD5-file found" exit 1 fi "$ECHO" "Generating our own checksum..." # MD5-Summe bilden if [ -f /etc/snort/snortrules-stable.tar.gz ] then MD5SUM2=`md5sum /etc/snort/snortrules-stable.tar.gz|awk '{print $1}'` else "$ECHO" "Error! No rules file found" exit 1 fi if [ "$MD5SUM1" = "$MD5SUM2" ] then "$ECHO" "The MD5-Checksum fits!" "$ECHO" "$MD5SUM1" "$ECHO" "$MD5SUM2" "$ECHO" "$MD5SUM1" >> /etc/snort/snort.log "$ECHO" "$MD5SUM2" >> /etc/snort/snort.log "$ECHO" "Proceeding..." # /bin/sleep 1 else "$ECHO" "Error! Wrong checksum! Aborting!" "$ECHO" "Install rules manually!" "$ECHO" "$MD5SUM1" >> /etc/snort/snort.log "$ECHO" "$MD5SUM2" >> /etc/snort/snort.log exit 1 fi # Extract the new rules if [ -f "/etc/snort/snortrules-stable.tar.gz" ] then "$ECHO" "Extracting Snort rules..." "$TAR" -xzvf /etc/snort/snortrules-stable.tar.gz -C /etc/snort else "$ECHO" "Lost the file! Something is wrong!" "$ECHO" "Aborting!!" exit 1 fi # Deleting old rules # Existiert das Verzeichnis ueberhaupt? if [ -d "$RULESPATH" ] then # /bin/rm "$RULESPATH"/*.rules /bin/mv -f /etc/snort/rules/*.rules "$RULESPATH" /bin/cp -f /etc/snort/rules/classification.config "$SNORTCFGPATH" else "$ECHO" "Missing rules-directory!" "$ECHO" "Aborting!" exit 1 fi # Cleaning up... /bin/rm -rf /etc/snort/rules # Give everything to root /bin/chown root:root ${RULESPATH}/* } ########################################################################### #### # M A I N # ########################################################################### #### # Error handling first FCHK=$(/usr/bin/wget -spider -N -t 3 -T 5 "$SIGS_URL1" -P /etc/snort 2>&1) ERR_MSG=$("$ECHO" "$FCHK" | egrep -oi "failed error") # Log the error message explicitly "$ECHO" "$FCHK" >> /etc/snort/snort.log # If there is a word "failed" or "error" we break.. if [ "$("$ECHO" "$FCHK"| grep -i "failed")" ] || \ [ "$("$ECHO" "$FCHK"| grep -i "error")" ] then "$ECHO" "Error getting the files. The server seems to be not available." "$ECHO" "Error message:" "$ECHO" "$FCHK" "$ECHO" "Aborting!" exit 0 fi "$ECHO" "Checking/getting files..." # First extract the wget message FCHK=$(/usr/bin/wget -spider -N -t 3 -T 5 "$SIGS_URL1" \ -P /etc/snort 2>&1 | grep "not retrieving") /bin/date >> /etc/snort/snort.log "$ECHO" "Wget-output:" "$ECHO" $FCHK # Logging what we've done and when "$ECHO" "$FCHK" >> /etc/snort/snort.log if [ -z "$FCHK" ] then "$ECHO" "The files on the server seem to be newer." "$ECHO" "We will get them now..." getrules # Reload rules "$SERVICE" snort reload # restartsnort else # "$ECHO" "The signature files on the server are older or not newer." "$ECHO" "Doing nothing for now..." "$ECHO" "Checking if Snort is running...." checksnort exit 0 fi # Send Email "$ECHO" -e "`ls -lA "$RULESPATH"`\n\nSnort running with PID $("$PIDOF"\ "$SNORT")" | mail -s "Reloaded Snort signatures on $MACHINE"\ "$MAILTO" ########################################################################### #### ########################################################################### #### exit 0 #EOF \end{verbatim} \subsection{How do I use a remote syslog machine?} Add the syslog switch, -s, and put this statement syslog.conf: \begin{verbatim} auth.alert @managmentserverIP \end{verbatim} Look at your snort.conf file for more info on the facility and Priority settings. Make sure you have syslogd on the management server configured to allow syslog over UDP. Under RedHat, you can do this by editing /etc/sysconfig/syslog and adding the following line: \begin{verbatim} SYSLOGD_OPTIONS="-r -m 0" \end{verbatim} This will start syslogd with the mark interval set to 0 (turning it off) and set it to receive network connections. Then restart syslog. ``man syslogd'' for more info. You might also want to investigate syslog-ng\linebreak (\htmladdnormallink{http://www.balabit.hu/en/downloads/syslog-ng/}{http://www.balabit.hu/en/downloads/syslog-ng/}). Example invocation of snort: \begin{verbatim} /usr/local/bin/snort -c /etc/snort/snort.conf -I -A full -s 192.168.0.2:514 -i rl0 \end{verbatim} Note for Win32 users: Frank Knobbe wrote a patch for Snort to allow you to use `-s $<$host$>$' on the command line under Windows without nullifying the snort.conf. In other words, Snort still uses all settings from snort.conf but in addition uses the host from `-s' to send syslog alerts to. You can find the patch at: \htmladdnormallink{http://www.snort.org/dl/contrib/patches/win32syslog/}{http://www.snort.org/dl/contrib/patches/win32syslog/} \subsection{How do I get Snort and ACID working?} Acid has been unmaintained for quite some time. Use BASE instead (see below). \subsection{How do I build this BASE thing?} Read carefully through all the docs for each package. Getting BASE to work is a lot of work, since it depends on many packages. You need a working Apache, a working PHP, a working GD (and the many libraries GD depends on) and the ADODB package. This is a lot of stuff to configure. A typical sequence to get this all working on Solaris 8: Use some binary packages from a trusted Sun freeware site (sunfreeware.com). The most problems were with PHP and the GD library. GD itself needs a bunch of packages and libraries to work also. It needs the libpng stuff, the libjpeg stuff (if you want jpeg), etc, etc. Read through the readme for GD. So you either need to get these and compile them also, or get some binary packages. PHP is the most difficult thing to get compiled correctly. The PHP package needs to be compiled with lots of ``-with'' flags for GD to work properly, otherwise it gets lots of run-time unresolved reference errors. Just using a ``with'' for GD isn't sufficient. You also need to "with" each library which GD uses also, or PHP can't find the functions it needs. Here's the ``configure'' line you can use to get PHP working: \begin{verbatim} ./configure --with-mysql --with-apxs=/usr/apache/bin/apxs --with-gd --enable-sockets --with-jpeg-dir=/usr/local/lib --with-png-dir=/usr/local/ lib --with-zlib-dir=/usr/local/lib --with-xpm-dir=/usr/local/lib \end{verbatim} These `with' statements basically have the effect of the Makefile including -L and -R statements for each library so that both the compile and run time linkers can find all the functions needed to find in the Apache module environment. Apache doesn't seem to consult the LD\_LIBRARY\_PATH when running a module (or PHP doesn't, or there's some config item in the Apache conf files, but you can just use the ``withs''). Basically, you need to work from the bottom up. So you need to obtain/compile any libraries that GD needs and install them, and any libraries/packages those packages need. Then once you get GD compiled properly and installed, compile PHP. Then make a PHP script that calls phpinfo() and carefully examine the page produced. Once satisfied PHP is working, then the 'foundation' is ready for the other stuff. If they succeed, then install ADODB and BASE, tweak the config files, and it should all work. (heh, heh) BASE website: \htmladdnormallink{http://base.secureideas.net/}{http://base.secureideas.net/} \section{Rules and Alerts} \subsection{Errors loading rules files} Some common ones: \begin{itemize} \item \begin{verbatim}ERROR telnet.rules:YYY => Port value missing in rule!\end{verbatim} \item \begin{verbatim}ERROR telnet.rules:YYY => Bad port number: "(msg:"blah"\end{verbatim} \item \begin{verbatim}ERROR telnet.rules:YYY => Couldn't resolve hostname blah\end{verbatim} \end{itemize} What's going on? ``telnet.rules'' is the file where the syntax error occurred, and ``YYY'' is the line number it occurred on. There are a couple of possibilities: \begin{enumerate} \item The rule is missing a port value, has an invalid port number, or a bad hostname - in which case the ruleset author/maintainer should be notified. \item More often, the rule is just fine, but a variable in it was not declared. Open the rules file, look at the rule on the line number provided, and confirm that the variables it uses have been declared. You can read more about variables at \htmladdnormallink{http://www.snort.org/docs/writing\_rules/chap2.html\#tth\_sEc2.1.2}{http://www.snort.org/docs/writing\_rules/chap2.html\#tth\_sEc2.1.2} \end{enumerate} \subsection{Snort says ``Rule IP addr (``1.1.1.1'') didn't x-late, WTF?''} Get rid of the quotes around the IP address and try again. \subsection{Snort is behind a firewall (ipf/pf/ipchains/ipfilter) and awfully quiet...} Your firewall rules will also block traffic to the Snort processes. Note: This does not apply if Snort is installed {\bf on} the firewall box. \subsection{Does snort see packets filtered by IPTables/IPChains/IPF/PF?} Snort operates using libpcap. In general it sees everything the network adapter driver sees before the network stack munges it. Linux IPTables, Linux IPChains, BSD PF and IPF and other packet filters do not prevent snort from seeing a packet that is present on the network wire. Even if an inbound packet is denied by the packet filter Snort will still see and analyze the packet if it is listening to that interface. Snort/pcap sees whatever comes out of or goes into the network adapter. Note however that Snort is affected to the extent that the stream of data on the network wire is affected. Thus Snort will not see outbound packets which were denied while being sent since they will never reach the network adapter. Under OpenBSD you can snort just the PF rejects by using the /dev/pflogN interface. \subsection{I'm getting large amounts of $<$some alerts type$>$. What should I do? Where can I go to find out more about it? } Some rules are more prone to producing false positives than others. This often varies between networks. You first need to determine if it is indeed a false positive. Some rules are referenced with ID numbers. The following are some common identification systems, and where to go to find more information about a particular alert. \begin{tabular}{|l|l|l|} \hline {\bf System} & {\bf Example} & {\bf URL} \\ \hline\hline IDS & IDS182 & \htmladdnormallink{http://www.whitehats.com/IDS/182}{http://www.whitehats.com/IDS/182} \\ \hline CVE & CVE-2000-0138 & \htmladdnormallink{http://cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2000-0138}{http://cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2000-0138} \\ \hline Bugtraq & BugtraqID 1 & \htmladdnormallink{http://www.securityfocus.com/vdb/bottom.html?vid=1}{http://www.securityfocus.com/vdb/bottom.html?vid=1} \\ \hline McAfee & Mcafee 10225 & \htmladdnormallink{http://vil.nai.com/vil/dispVirus.asp?virus\_k=10225}{http://vil.nai.com/vil/dispVirus.asp?virus\_k=10225} \\ \hline Nessus & Nessus 11073 & \htmladdnormallink{http://cgi.nessus.org/plugins/dump.php3?id=11073}{http://cgi.nessus.org/plugins/dump.php3?id=11073}\\ \hline \end{tabular} It may be necessary to examine the packet payload to determine if the alert is a false positive. The packet payload is logged using the -d option. If you determine the alerts are false positives, you may want to write pass rules for machines that are producing a large number of them. If the rule is producing an unmanageable amount of false positives from a number of different machines, you could pass on the rule for all traffic. This should be used as a last resort. \subsection{What about all these false alarms? } Most think that a pile of false positives is infinitely preferable. Then people can turn off what they don't want. The reverse, having a small rule set, can lure people into complacency thinking that Snort is doing ``its thing'' and there is nothing to worry about. \subsection{What are all these ICMP files in subdirectories under /var/log/snort? } Most of them are likely destination unreachable and port unreachables that were detected by snort when a communications session attempt fails. \subsection{Why does the program generate alerts on packets that have pass rules? } The default order that the rules are applied in is alerts first, then pass rules, then log rules. This ordering ensures that you don't write 50 great alert rules and then disable them all accidentally with an errant pass rule. If you really want to change this order so that the pass rules are applied first, use the ``-o'' command line switch, or the ``order'' config directive. One other thing to keep in mind is that the alert might be generated from a preprocessor. If that is the case, then no pass rule will help you minimize the false positives. You will need to use a BPF filter. \subsection{What are all these ``ICMP destination unreachable'' alerts? } ICMP is the acronym for Internet Control Message Protocol They are failed connections ICMP unreach packet carries first 64 bits(8bytes) or more of the original datagrami and the original IP header. The ICMP Destination Unreachable (message type 3) is sent back to the originator when an IP packet could not be delivered to the destination address. The ICMP Code indicates why the packet could not be delivered. The original codes are: \begin{itemize} \item0 - net unreachable \item1 - host unreachable \item2 - protocol unreachable \item3 - port unreachable \item4 - fragmentation needed and DF bit set \item5 - source route failed \end{itemize} As far as why... ``it all depends...'' ICMP Unreachable Error Messages are divided into two groups: \begin{enumerate} \item ICMP Unreachable Error Messages issued by routers (all 16 of them) \item ICMP Unreachable Error Messages issued by a Host (only 2) \end{enumerate} What are the only 2 issued by a host? ICMP Port Unreachable - the destination port on the targeted host is closed (a.k.a. not in a listening state). ICMP Protocol Unreachable - the protocol we were trying to use is not being used on the targeted host. Both ICMP Type field and Code field indicates why the packets could not be delivered. Some snort ICMP alerts" are informational like the ICMP alerts found in icmp-info.rules. At this time there are no references or even classtypes associated with these rules. Other rules are more likely to be associated with untoward activity. For example, in icmp.rules you will find: \begin{verbatim} alert icmp $EXTERNAL_NET any -> $HOME_NET any (msg:"ICMP ISS Pinger"; content:"|495353504e475251|";itype:8;depth:32; reference:arachnids,158; classtype:attempted-recon; sid:465; rev:1;) \end{verbatim} which has a reference where the importance might be determined by checking out the arachnids reference. The classtype may indicate more or less the relative importance of the event. When a destination UDP port is closed on the targeted host, a.k.a. not in a listening state, the targeted host will issue an ICMP Port Unreachable error message back to the offending packets source IP address, given in the query. Some programs use these messages, like traceroute with *nix based machines. Windows based machines (tracert) will default to ICMP Echo requests... For further information about this, see: \begin{itemize} \item IP - ftp://ftp.isi.edu/in-notes/rfc791.txt \item ICMP - ftp://ftp.isi.edu/in-notes/rfc792.txt \item TCP - ftp://ftp.isi.edu/in-notes/rfc793.txt \item UDP - ftp://ftp.isi.edu/in-notes/rfc768.txt \end{itemize} and \htmladdnormallink{http://www.iana.org/assignments/icmp-parameters}{http://www.iana.org/assignments/icmp-parameters} Actually, putting this URL somewhere handy is a good idea: \htmladdnormallink{http://www.iana.org/}{http://www.iana.org/} There is also a good ICMP paper on \htmladdnormallink{http://www.sys-security.com/}{http://www.sys-security.com/} \subsection{Why do many Snort rules have the flags P (TCP PuSH) and A (TCP ACK) set? } One of the reasons it alerts on a PA flags is to minimize the false positive. You will only get an alert upon successful connections. If you want to see all the attempts, you either have to modify the signatures, add you own signatures or use your firewall logs to see if an attempt to specific a port occurred. \subsection{What are these IDS codes in the alert names? } IDS means "Intrusion Detection Signature" and identifies a known attack attempt. You can learn more about a specific IDS id at the arachNIDS search engine on \htmladdnormallink{http://www.whitehats.com/}{http://www.whitehats.com/}. The ``references'' keyword in rules can also be a good pointer for further research. \subsection{Snort says BACKDOOR SIGNATURE... does my machine have a Trojan? } If you are dumping the data part of the packet, review it. These rules are known to have high false rates as most of them are just based on numeric port numbers. \subsection{What about ``CGI Null Byte attacks?'' } It's a part of the http preprocessor. Basically, if the http decoding routine finds a \%00 in an http request, it will alert with this message. Sometimes you may see false positives with sites that use cookies with urlencoded binary data, or if you're scanning port 443 and picking up SSLencrypted traffic . If you're logging alerted packets you can check the actual string that caused the alert. Also, the unicode alert is subject to the same false positives with cookies and SSL. Having the packet dumps is the only way to tell for sure if you have a real attack on your hands, but this is true for any content-based alert. \subsection{Why do certain alerts seem to have `unknown' IPs in BASE? } See the BASE FAQ at \htmladdnormallink{http://base.secureideas.net/faq.php}{http://base.secureideas.net/faq.php} \subsection{Can priorities be assigned to alerts using BASE? } See the BASE FAQ at \htmladdnormallink{http://base.secureideas.net/faq.php}{http://base.secureideas.net/faq.php} \subsection{What about `SMB Name Wildcard' alerts? } Whitehats IDS177 \htmladdnormallink{http://dev.whitehats.com/cgi/test/new.pl/Show?\_id=netbios-name-query}{http://dev.whitehats.com/cgi/test/new.pl/Show?\_id=netbios-name-query} specifies traffic coming from {\em outside} of your local network. Allowing netbios traffic over public networks is usually very insecure. If the rule you are using also refers to ingres traffic only, then it would explain why you don't see a lot of false positives. For anyone reading that does see a lot of false postiives - if you change your rule to reflect the source address as being !\$HOME (or whatever variable you use to represent your internal network), then you should see most of the false positives go away. The value of this chack is that a default administrative share C\$ ADMIN\$ or some such has been accessed. This shouldn't happen in normal use - when people want to share files they should be implicitely defining the shares and ACL. \subsection{What the heck is a SYNFIN scan? } SYNFIN scans got their name because there are both the SYN and FIN flags set. \subsection{I am getting too many ``IIS Unicode attack detected'' and/or ``CGI Null Byte attack detected'' false positives. How can I turn this detection off? } These messages are produced by the http\_decode preprocessor. If you wish to turn these checks off, add -unicode or -cginull to your http\_decode preprocessor line respectively. \begin{verbatim}preprocessor http_decode: 80 8080 -unicode -cginull\end{verbatim} Your own internal users normal surfing can trigger these alerts in the preprocessor. Netscape in particular has been known to trigger them. Instead of disabling them,try a BPF filter to ignore your outbound http traffic such as: \begin{verbatim}snort -d -A fast -c snort.conf not (src net xxx.xxx and dst port 80)\end{verbatim} This has worked very well for us over a period of 5-6 months and Snort is still very able to decode actual and dangerous cgi null and unicode attacks on our public web servers. \subsection{How do I test Snort alerts and logging?} Try a rule that will fire off all the time like: \begin{verbatim}alert tcp any any -> any any (msg:"TCP traffic";)\end{verbatim} Also take a look at sneeze at http://snort.sourceforge.net/sneeze-1.0.tar Sneeze is a false positive generator that reads snort signatures and generates packets that will trigger the rules. \subsection{What is the difference between ``Alerting'' and ``Logging''?} There are two primary output facilities in Snort, logging and alerting. The alerting facility exists to let you know that something interesting has happened. The logging facility exists to log full packet information to the output format (pcap, ascii, database, etc). The ``alert'' action in Snort is hard coded to do two things when an event is detected by Snort, write an event to the alert facility and log as much as possible/desired to the output facility. The ``log'' action merely logs the current packet to the logging facility without generating an alert. This is done so you can log interesting things (telnet sessions, whatever) without having to generate an alert on every packet. The database plugin is something of an anomaly because it doesn't separate the two functionalities very much. The ``log'' option attaches the log facility and the ``alert'' option attaches it to the alert facility. What this means in practical terms is that if the db plugin is in alert mode, it will only receive output from alert rules, whereas if it's in ``log'' mode it will receive output from both log and alert rules. \subsection{Are rule keywords ORed or ANDed together?} >From Section 2.1 of the Snort Manual: \myquote{ All of the elements in that make up a rule must be true for the indicated rule action to be taken. When taken together, the elements can be considered to form a logical AND statement. At the same time, the various rules in a Snort rules library file can be considered to form a large logical OR statement. } \subsection{Can Snort trigger a rule by MAC addresses?} Not exactly. Snort logs MAC addresses and other L2 info within the packets. The arpwatch pre-processor can watch for games with MAC address changes. But there is no facility for triggering Rules form the L2 information. The content search keywords and depth and offset begin from the L3 payload, though we haven't tried playing with really big offsets yet :-). \subsection{How can I deactivate a rule?} Rules can be called from an included file in snort.conf, which tells Snort to follow the path to the rules file specified, and load it at initialization. Rules can also be included in snort.conf directly. If you want to deactivate a single rule within any list of rules, you can use one of these techniques: \begin{enumerate} \item Delete the rule and re-initialize Snort \item Place a \# in front of the rule, commenting it out, and re-initialize Snort \item Write a pass rule with the same properties in local.rules (or wherever you prefer), and re-initialize Snort with the -o option. \end{enumerate} \subsection{How can I define an address to be anything except some hosts?} Use the ! operator. E.g.: \begin{verbatim} var EXTERNAL_NET !$HOME_NET \end{verbatim} Note that the negation operator does not work inside a list so the following will NOT work: \begin{verbatim} var EXTERNAL_NET [!192.168.40.0/24,!10.14.0.0/16] \end{verbatim} but this will work: \begin{verbatim} var EXTERNAL_NET ![192.168.40.0/24,10.14.0.0/16] \end{verbatim} \subsection{After I add new rules or comment out rules how do I make Snort reload?} Usually a kill -HUP will work just fine. But if you are running inside of a chroot setup, this will not work as expected \myref{chroot}. If you're running like inside of a chroot jail, your best bet would be to kill and restart the snort process instead. \subsection{Where do the distance and within keywords work from to modify content searches in rules?} The ``distance'' keyword gives you a relative offset from the end of the last match, so it basically acts as a wildcarding mechanism. You can also use the new ``within'' keyword to limit how deep into the packet from the end of the distance it'll search before it stops. \subsection{How can I specify a list of ports in a rule?} You can't yet. You can specify a range of ports between X and Y with the notation X:Y. See the users manual (\htmladdnormallink{http://www.snort.org/docs/writing\_rules/chap2.html\#tth\_sEc2.2.4}{http://www.snort.org/docs/writing\_rules/chap2.html\#tth\_sEc2.2.4}) for more info on port ranges. \subsection{How can I protect web servers running on ports other than 80?} It is possible... It's a kludge, but it can work. Since the newer rules use the \$HTTP\_PORTS variable, you simply reset it and re-run the rules for the other ports. For example: \begin{verbatim} var HTTP_PORTS 80 include web.rules var HTTP_PORTS 8080 include web.rules \end{verbatim} \subsection{How do I turn off ``spp:possible EVASIVE RST detection'' alerts?} You want to pass the ``disable\_evasion\_alerts'' argument to stream4 in snort.conf. \subsection{Is there a private SID number range so my rules don't conflict?} Yes. Private SIDs start at 1000000. \subsection{How long can address lists, variables, or rules be?} The Snort parser has an 8K limit on variables and rules {\bf after} expansion. In practice, this is not a major limitation. :-) \subsection{What do the numbers (ie: [116:56:1]) in front of a Snort alert mean?} For this explanation, we'll use the following example: \begin{verbatim} [**] [116:56:1] (snort_decoder): T/TCP Detected [**] \end{verbatim} The first number is the Generator ID, this tells the user what component of Snort generated this alert. For a list of GIDs, please read etc/generators in the Snort source. In this case, we know that this event came from the ``decode'' (116) component of Snort. The second number is the Snort ID (sometimes referred to as Signature ID). For a list of preprocessor SIDs, please see etc/gen-msg.map. Rule-based SIDs are written directly into the rules with the ``sid'' option. In this case, ``56'' represents a T/TCP event. The third number is the revision ID. This number is primarily used when writing signatures, as each rendition of the rule should increment this number with the ``rev'' option. \section{Getting Fancy} \subsection{I hear people talking about ``Barnyard''. What's that?\label{barnyard}} Barnyard is a output system for Snort. Snort creates a special binary output format called ``unified.'' Barnyard reads this file, and then resends the data to a database backend. Unlike the database output plugin, Barnyard is aware of a failure to send the alert to the database, and it stops sending alerts. It is also aware when the database can accept connections again and will start sending the alerts again. \subsection{Are there other output systems for Snort besides ``Barnyard''?\label{spoolers}} FLoP (Fast Logging Project) and Mudpit are two other programs that can be used. FLoP adds a patch to Snort that creates an output plugin that writes alerts to a Unix domain socket instead of a file. These alerts (which are stored in memory) are then sent to a central server where they are then written to a database. Advantages are that database requests are made locally rather than over the wire and files don't need to be stored on the sensor. \htmladdnormallink{http://www.geschke-online.de/FLoP/}{http://www.geschke-online.de/FLoP/} Mudpit is similar to Barnyard in that it uses Snort's unified output. It however has the ability to process both alert and log files in parallel, choosing one that contains more information on a particular event. \htmladdnormallink{http://farm9.org/Mudpit/}{http://farm9.org/Mudpit/} \subsection{How do I process those Snort logs into reports?} \begin{enumerate} \item Barnyard \myref{barnyard} can be used to process unified output files into a number of formats, including output to a database for further analysis. \item SnortSnarf, a tool for producing HTML out of snort alerts for navigating through these alerts. % \htmladdnormallink{http://www.silicondefense.com/snortsnarf/}{http://www.silicondefense.com/snortsnarf/} \item If you want to set up logging to a database you could try BASE: \htmladdnormallink{http://base.secureideas.net/}{http://base.secureideas.net/} \item You can manipulate the unified output files directly without a separate database and browse/correlate them with Cerebus: \htmladdnormallink{http://dragos.com/cerebus/}{http://dragos.com/cerebus/} \item For GUI front ends with simple log browsing, look at: \begin{itemize} \item HenWen (OSX) \htmladdnormallink{http://homepage.mac.com/nickzman}{http://homepage.mac.com/nickzman} \htmladdnormallink{http://home.attbi.com/~rickzman/software/HenWen1.0.sit.bin}{http://home.attbi.com/~rickzman/software/HenWen1.0.sit.bin} \item IDS Center (Win32) \label{IDSCenter} \htmladdnormallink{http://www.packx.net/}{http://www.packx.net/} \item Puresecure (UNIX and Win32) (Formerly known as Demarc.) \htmladdnormallink{http://www.demarc.com/downloads/puresecure/}{http://www.demarc.com/downloads/puresecure/} \item SnortCenter (UNIX and Win32) \htmladdnormallink{http://users.pandora.be/larc/}{http://users.pandora.be/larc/} \item IDS Policy Manager (Win32) \htmladdnormallink{http://www.activeworx.com/IDSPM/}{http://www.activeworx.com/IDSPM/} \end{itemize} \end{enumerate} \subsection{How do I log to multiple databases or output plugins?} Feed the unified output files through Barnyard twice to separate databases, or... You can build redundancy by using multiple output plugins. Here are some examples. Multiple instantiations of the database plugin: \begin{verbatim} output log_database: mysql, dbname=snort host=localhost user=xyz output log_database: mysql, dbname=snort host=remote.loghost.com user=xyz \end{verbatim} Remote database and local tcpdump: \begin{verbatim} output log_database: mysql, dbname=snort host=remote.loghost.com user=xyz output log_tcpdump: /var/log/snort.tcpdump \end{verbatim} Then you can replay the tcpdump file through snort to recreate the database. CAVEAT: Just playing back the log packets might not trigger some of the state dependent pre-processors. \subsection{How can I test Snort without having an Ethernet card or a connection to other computers? } You have to use routing between two dummy devices: \begin{verbatim} modprobe -a dummy # (The dummy device has to be build by the kernel) ifconfig dummy0 192.168.0.1 ifconfig dummy0:0 192.168.0.2 telnet 192.168.0.3 12345 \end{verbatim} It's important that the second IP is on the same interface and not, e.g. dummy1 or dummy2 and that the IP you try to access is {\em not} one of those you put on the interfaces. Use snort's ability to hear in promiscious mode on an IP address range. (HOME\_NET=192.168.0.0/16) \subsection{How to start Snort as a win32 service? } \begin{enumerate} \item You must use complete paths for everything. This means EVERYTHING: Command line, configuration files, everything. Examples: All include statements must be full paths: WRONG: include scan-lib CORRECT: include C:\( \backslash \)snort\( \backslash \)scan-lib All command line options must be full paths: WRONG: snort.exe -l ./log CORRECT: snort.exe -l C:\( \backslash \)snort\( \backslash \)log \item YOU MUST ALWAYS HAVE A LOGGING DIRECTORY SET VIA THE COMMAND LINE (-l switch). If you do not set a logging directory the service will not start and, on NT/Win2k, your bootup will hang for about 4 minutes. \item Make sure that snort runs correctly from the command line, without yet worrying about any service related issues. Test that all of your desired command line parameters are causing snort to function as you expect, such as correctly generating logging and alert output. If you can't get this part to work, then you don't have much hope of snort miraculously starting to work as a service. \item Once you have step (3) running correctly, modify the command line parameters you used in step (3) to include the additional parameters ``/SERVICE /INSTALL.'' For example, if your command line in step (3) was: \begin{verbatim} snort -i1 -lC:\( \backslash \)snort\( \backslash \)log -cC:\( \ backslash \)snort\( \backslash \)snort.conf \end{verbatim} then you should change it to be: \begin{verbatim} snort /SERVICE /INSTALL -i1 -lC:\( \backslash \)snort\( \backslash \) log -cC:\( \backslash \)snort\( \backslash \)snort.conf \end{verbatim} Verify that the command line parameters were received correctly by running the command `snort /SERVICE /SHOW.' \item Start the service by running the command: \begin{verbatim} net start snortsvc \end{verbatim} Note that versions 1.9 (build 228), 2.0 (build 50), or any versions newer than these, will add entries to the Win32 event Log if there is ever a problem starting the service. Stop the service by running the command: \begin{verbatim} net stop snortsvc \end{verbatim} \item The service can be uninstalled by running the command: \begin{verbatim} snort /SERVICE /UNINSTALL \end{verbatim} \end{enumerate} \subsection{Is it possible with snort to add a ipfilter/ipfw rule to a firewall? } Yes. Select the appropriate DAQ module for your system. IPQ, NFQ, and IPFW DAQs are available, among others. See README.daq for details. Other possibilities are listed below. \begin{itemize} \item SnortSam \htmladdnormallink{http://www.snortsam.net}{http://www.snortsam.net} \item You also might wat to look at inline-snort at: \htmladdnormallink{http://www.snort.org/dl/contrib/patches/snort-inline}{http://www.snort.org/dl/contrib/patches/snort-inline} \item Guardian is available and is part of the contrib section at \htmladdnormallink{http://www.snort.org}{http://www.snort.org}. Guardian is a perl script which uses Snort to detect attacks, and then uses IPchains to deny any further attacks. The Guardian webpage can be found at: \htmladdnormallink{http://www.chaotic.org/~astevens/Guardian/index.html}{http://www.chaotic.org/~astevens/Guardian/index.html} or you can use the mirror, \htmladdnormallink{http://www.cyberwizards.com/~midnite/Guardian/index.html}{http://www.cyberwizards.com/~midnite/Guardian/index.html} \end{itemize} But one caveat... running external binaries can also be a performance limiter and your should read the caution below... CHRISTOPHER CRAMER wrote: \myquote{ I'm sure this has been mentioned before in similar discussions, but this feels like a \_really\_ bad idea. What if the bad guys realize what is going on and make use of your blocking method as a DoS attack. All one would have to do start sending a series of triggering packets with spoofed IP addresses. Since I am no longer interested in breaking into your site, but rather making your life hell, I don't worry about the resulting data getting back to me. All I have to do is start proceeding up a list of IP addresses that I think you should no longer be able to talk to. When you come in the next morning, you find that you can no longer access the world. Just my \$0.02. } Danger Will Robinson: Conventional wisdom says that auto-blocking is inherently dangerous. However, for those that like to live at the bleeding edge of tech (and the separate process scanning logs and processing firewall commands sounds like a good way to do this...): Please remember to include an exclusion list and put on them important sites such as root servers, other important dns servers (yours, and important sites for your users), and in general any host you don't want to receive phone calls about being DoSed when they are spoofed - usually inconveniently like that first time you actually manage to get on vacation.... (i.e. imagine ``Crisis: the CEO can't reach his favorite redlite.org game.... you have to fly back from the Carribean ASAP....'') \subsection{What is the best way to use Snort to block attack traffic?} \begin{verbatim}snort-inline > hogwash >> SnortSAM|Guardian >> flexresp\end{verbatim} \subsection{Snort complains about the ``react'' keyword...} Rerun configure with the --enable-flexresp option and rebuild/reinstall. \subsection{How do I get Snort to e-mail me alerts?} You can't. Such a process would slow Snort down too much to make it of any use. Instead, log to syslog and use swatch or logcheck to parse over the plaintext logfiles. With the Logsurfer docs, this might get you on the road to doing something with Snort and Logsurfer: \begin{itemize} \item \htmladdnormallink{http://www.obfuscation.org/emf/logsurfer/snort.txt}{http://www.obfuscation.org/emf/logsurfer/snort.txt} \end{itemize} JASON HAAR provided an example Swatch (3.1beta) config that emails alerts: \begin{itemize} \item \htmladdnormallink{http://www.theadamsfamily.net/~erek/snort/snort-swatch.conf.txt}{http://www.theadamsfamily.net/~erek/snort/snort-swatch.conf.txt} \end{itemize} Here are some docs on swatch: \begin{itemize} \item \htmladdnormallink{http://www.oit.ucsb.edu/~eta/swatch/}{http://www.oit.ucsb.edu/~eta/swatch/} \item \htmladdnormallink{http://www.stanford.edu/~atkins/swatch}{http://www.stanford.edu/~atkins/swatch} \item \htmladdnormallink{http://rr.sans.org/sysadmin/swatch.php}{http://rr.sans.org/sysadmin/swatch.php} \item \htmladdnormallink{http://www.enteract.com/~lspitz/swatch.html}{http://rr.sans.org/sysadmin/swatch.php} \item \htmladdnormallink{http://www.cert.org/security-improvement/implementations/i042.01.html}{http://www.cert.org/security-improvement/implementations/i042.01.html} \end{itemize} IDS Center \myref{IDSCenter} on Win32 will also mail alerts. \subsection{How do I log a specific type of traffic and send alerts to syslog?} An example addition to snort.conf: \begin{verbatim} ruletype redalert { type alert output alert_syslog: LOG_LOCAL2 output database: alert, postgresql, user=user dbname=snort password=pwd } \end{verbatim} Go into your local.rules and make sure you have something like: \begin{verbatim} redalert tcp any any -> any any (msg:"REDRUM REDRUM"; content:"redalerttest") \end{verbatim} Then just do a telnet and type `redalerttest.' Presto, alerts to both. \subsection{Is it possible to have Snort call an external program when an alert is raised?} Calling another program from within your main IDS loop is generally a bad idea. Having your IDS block while waiting for $<$something$>$ of dubious reliability and origin nevermind timing while the packets are piling up is inviting packet loss. Especially with the already oh-so-consistent ``Gee I think I'll go away for a minute'' rock steady even cpu slicing Windows gives you (that's sarcasm, sorry). Go with the second approach.... process invokation is expensive on Windows. You want to keep that IDS task humming and munching packets as efficiently as possible with as few interruptions as possible, imho, and not be invoking the penalty of process invocation.... particularly on Windows where process invocation is much much heavier task than *nix. Even in a secondary process... You'll probably find something that stays ``awake'' all the time will work out much more nicely than something that gets ``woken up'' on a per alert basis for the aforementioned reasons. As a better alternative go check out swatch or logwatch. Also for those new to UNIX, logging alerts to syslog and then using ``tail -f /var/log/messages'' might be what you are looking for. \subsection{How can I use Snort to log HTTP URLs or SMTP traffic?} It can be done with Snort, but you might find it faster to use mailsnarf and urlsnarf from Dug Song's dsniff package. Dsniff is available from: \htmladdnormallink{http://www.monkey.org/~dsong/dsniff/}{http://www.monkey.org/~dsong/dsniff/} You can get a win32 port of dsniff at: \htmladdnormallink{http://www.datanerds.net/~mike/dsniff.html}{http://www.datanerds.net/~mike/dsniff.html} \subsection{What are some resources that I can use to understand more about source addresses logged and where they are coming from?} \begin{itemize} \item \htmladdnormallink{http://www.arin.org/}{http://www.arin.org/} \item \htmladdnormallink{http://www.caida.org/tools/utilities/netgeo/}{http://www.caida.org/tools/utilities/netgeo/} \item \htmladdnormallink{http://netgeo.caida.org/perl/netgeo.cgi}{http://netgeo.caida.org/perl/netgeo.cgi} \item \htmladdnormallink{http://standards.ieee.org/regauth/oui/oui.txt}{http://standards.ieee.org/regauth/oui/oui.txt} \item \htmladdnormallink{http://www.codito.de/manufactor\_hash}{http://www.codito.de/manufactor_hash} \item \htmladdnormallink{http://coffer.com/mac\_find/}{http://coffer.com/mac_find/} \item \htmladdnormallink{http://www.idefense.com/Intell/CI022702.html}{http://www.idefense.com/Intell/CI022702.html} \item \htmladdnormallink{http://www.idefense.com/excelfiles/All.zip}{http://www.idefense.com/excelfiles/All.zip} \end{itemize} Also, try ``dig.'' \subsection{How do I understand this traffic and do IDS alert analysis?} \begin{enumerate} \item You'll need to understand some basics of IP, TCP, and UDP. Things like destination addresses, source addresses, common ports, what TCP SYN, FIN and RST mean, etc. The same kind of basic knowledge of the internet you need to successfully configure a multi-interface router applies here, although you don't need to know router syntax. Some useful online references: \begin{itemize} \item A truly basic ``intro to TCP/IP'' \htmladdnormallink{http://pclt.cis.yale.edu/pclt/COMM/TCPIP.HTM}{http://pclt.cis.yale.edu/pclt/COMM/TCPIP.HTM} \item A reasonable looking TCP/IP FAQ: \htmladdnormallink{http://www.itprc.com/tcpipfaq/default.htm}{http://www.itprc.com/tcpipfaq/default.htm} \item A basics of firewalls, DMZ's, etc. \htmladdnormallink{http://www.ibiblio.org/pub/Linux/docs/HOWTO/other-formats/html\_single/Firewall-HOWTO.html}{http://www.ibiblio.org/pub/Linux/docs/HOWTO/other-formats/html_single/Firewall-HOWTO.html} \end{itemize} \item You'll need to understand some basics of how network attacks work. I'd recommend skimming over ``Smashing the Stack for fun and profit'' by Aleph one. A deep understanding isn't necessary, but a casual read of this will give you some helpful basics in understanding the kinds of things that happen in an attack, and give you a better understanding of what to look for. \htmladdnormallink{http://www.insecure.org/stf/smashstack.txt}{http://www.insecure.org/stf/smashstack.txt} \item A good guide on securing systems is helpful, something like this one: \htmladdnormallink{http://www.openna.com/products/books/sol/solus.php}{http://www.openna.com/products/books/sol/solus.php} \htmladdnormallink{http://www.seifried.org/lasg/}{http://www.seifried.org/lasg/} \item You'll need to understand the basics of internet servers, ie: what DNS, HTTP, FTP, SMTP, etc. are for. Most of that should be covered in the various other references made here. \item An excellent reference on ``oddball'' traffic patterns commonly seen at network borders, also very helpful: \htmladdnormallink{http://www.robertgraham.com/pubs/firewall-seen.html}{http://www.robertgraham.com/pubs/firewall-seen.html} \item Also take a look at the ``Recommended Reading'' section \myref{courses} \end{enumerate} \subsection{How can I examine logged packets in more detail?} If you are using unified logging, you can use Barnyard \myref{barnyard} or the unified log to pcap converter written by Dragos: \htmladdnormallink{http://dragos.com/logtopcap.c}{http://dragos.com/logtopcap.c} You can also use the \texttt{getpacket} program from the FLoP project \myref{spoolers} You can then get additional decoding of the packet contents by analyzing these pcap files with either: \begin{itemize} \item Tcpdump - http://www.tcpdump.org \item Ethereal - http://www.ethereal.com \end{itemize} \section{Problems} \subsection{ I think I found a bug in Snort. Now what?} Get some more diagnostic information and post it to ``snort-users'' at \htmladdnormallink{http://www.sourceforge.net/lists/listinfo/snort-users}{http://www.sourceforge.net/lists/listinfo/snort-users}. To get diagnostic information, compile snort as either: \begin{verbatim}make clean; make CFLAGS=-ggdb\end{verbatim} or \begin{verbatim}make clean; make "CFLAGS=-ggdb -DDEBUG" \end{verbatim} trace coredump as: \begin{verbatim} gdb /path/to/snort /path/to/snort/core gdb> where gdb> bt gdb> print $varname, varname, \$\$varname etc.. \end{verbatim} or if corefile isn't generated, Snort should be started as: \begin{verbatim} gdb snort gdb> run snort\_args\_go\_here \end{verbatim} Then, when it crashes: \begin{verbatim} gdb> where gdb> bt gdb> print \$varname, varname, \$\$varname etc.. \end{verbatim} \subsection{SMB alerts aren't working, what's wrong? } The SMB alerting output plugin was removed in Snort 2.1 due to security issues. \subsection{Snort says ``Garbage Packet with Null Pointer discarded!'' Huh?} This was an internal diagnostic message triggered by an old bug in early versions of the defragmentation preprocessor. Upgrade to to the latest version of Snort. \subsection{Snort says ``Ran Out Of Space.'' Huh?} This is an internal diagnostic message when the defragmentation preprocessor runs into its ~32MB hard allocation space limit. Tell Dragos about it $<$dr@kyx.net$>$. \subsection{My BASE db connection times-out when performing long operations (e.g. deleting a large number of alerts).} PHP has an internal variable set to limit the length an script can execute. It is used to prevent poorly written code from executing indefinitely. In order to modify the time-out value, examine the 'max\_execution\_time' variable found in the 'php.ini' configuration file. \subsection{Why does snort report ``Packet loss statistics are unavailable under Linux?''} The Linux IP stack doesn't report lost packet stats. This also has been recently fixed with the 2.4+ kernel in the new version of libpcap...upgrade kernels and libpcap and it should now work. \subsection{My /var/log/snort directory gets very large...} Try this script to archive the files: \begin{verbatim} * []#!/bin/sh # # Logfile rotation script for snort written by jameso@elwood.net. # # This script is pretty basic. We start out by setting some vars. # Its job is tho rotate the days logfiles, e-mail you with what # it logged, keep one weeks worth of uncompressed logs, and also # keep compressed tgz files of all the logs. It is made to be run # at midnight everynight. This script expects you to have a base # dir that you keep all of your logs, rule sets etc in. You can # see what sub dirs it expects from looking at the var settings # below. # # Things to note in this script is that we run this script at 12 # every night, so we want to set the dirdate var the day the script # runs minus a day so we label the files with the correct day. We # Then create a dir for the days logs, move the log files into # todays dir. As soon as that is done restart snort so we don't miss # anything. Then delete any logs that are uncompressed and over a # week old. Then compress out todays logs and archive them away, and # end up by mailling out the logs to you. # # Define where you have the base of your snort install snortbase=/usr/snort # Define other vars # logdir - Where the logs are kept # oldlogs - Where you want the archived .tgz logs kept # weeklogs - This is where you want to keep a weeks worth of log files uncompressed # dirdate - Todays Date in Month - Day - Year format # olddirdate - Todays date in the same format as dirdate, minus a week logdir=$snortbase/log oldlogs=$snortbase/oldlogs weeklogs=$snortbase/weeklogs # When I first wrote this script, I only ran it on BSD systems. That was a # mistake, as BSD systems have a date command that apperently lets you walk the # date back pretty easily. Well, some systems don't have this feature, so I had # to change the way that dates are done in here. I left in the old way, because # it is cleaner, and I added in a new way that should be portable. If anyone # has any problems, just let me know and I will try to fix it. # # You have to change the system var to either bsd or other. Set it to bsd if # your system supports the "-v" flag. If you are not sure, set it to other. system=bsd if [ $system = bsd ] then dirdate=`date -v -1d "+%m-%d-%y"` olddirdate=`date -v -8d "+%m-%d-%y"` elif [ $system = other ] month=`date "+%m"` yesterday=`expr \`date "+%d"\` - 1` eightday=`expr \`date "+%d"\` - 8` year=`date "+%y"` dirdate=$month-$yesterday-$year olddirdate=$month-$eightday-$year fi # Create the Dir for todays logs. if [ ! -d $weeklogs/$dirdate ] then mkdir $weeklogs/$dirdate fi # Move the log files into todays log dir. This is done with # a for loop right now, because I am afriad that if a lot is # logged there may be to many items to move with a "mv *" # type command. There may a better way to do this, but I don't # know it yet. for logitem in `ls $logdir` ; do mv $logdir/$logitem $weeklogs/$dirdate done # Kill and restart snort now that the log files are moved. kill `cat /var/run/snort_fxp0.pid` # Restart snort in the correct way for you /usr/local/bin/snort -i fxp0 -d -D -h homeiprange/28 -l /usr/snort/log \ -c /usr/snort/etc/08292k.rules > /dev/null 2>&1 # Delete any uncompressed log files that over a week old. if [ -d $weeklogs/$olddirdate ] then rm -r $weeklogs/$olddirdate fi # Compress and save the log files to save for as long as you want. # This is done in a sub-shell because we change dirs, and I don't want # to do that within the shell that the script runs in. (cd $weeklogs; tar zcvf $oldlogs/$dirdate.tgz $dirdate > /dev/null 2>&1) # Mail out the log files for today. cat $weeklogs/$dirdate/snort.alert | mail -s "Snort logs" you@domain.com cat $weeklogs/$dirdate/snort_portscan.log | mail -s "Snort portscan logs" you@do main.com \end{verbatim} \subsection{Why does the `error deleting alert' message occur when attempting to delete an alert with BASE? } Most likely the DB user configure in BASE does not have sufficient privileges. In addition to those privileges granted to log the alerts into the database (INSERT, SELECT), DELETE is also required. This permission related issue can be confirmed by manually inserting a row into the database, then trying to delete it. \begin{enumerate} \item Log into MySQL with the same credentials (i.e. username, password) as you use in BASE: \begin{verbatim} mysql -u -p \end{verbatim} \item Insert a test row into the event table: \begin{verbatim} mysql> INSERT INTO event (sid, cid, signature, timestamp) VALUES (1,1000000, "test", "0"); \end{verbatim} (this assumes that you don't already have a row with an event ID=1000000. If you do just choose another event id \#) \item Now delete this newly inserted row: \begin{verbatim}mysql> DELETE FROM event WHERE sid=1 AND cid=10000000; \end{verbatim} If you were not able to delete, this confirms that this is a permission problem. Re-login to mysql as root, and issue a GRANT command (giving the DELETE permission) to the BASE DB user: \begin{verbatim}GRANT DELETE on snort.* to base@localhost\end{verbatim} (this assumes that my alert database is 'snort', username is 'base', and logging from the 'localhost') \end{enumerate} \subsection{BASE appears to be broken in Lynx } See the BASE FAQ at \htmladdnormallink{http://base.secureideas.net/faq.php}{http://base.secureideas.net/faq.php} \subsection{I am getting `snort [pid] uses obsolete (PF\_INET, SOCK\_PACKET)' warnings. What's wrong?} You are using an older libpcap version with recent linux kernel. There should be no problem with it as long as your kernel supports SOCK\_PACKET socket type. To get rid off the warning message however, you'll have to upgrade to some recent version of libpcap (a copy from www.tcpdump.org is recommended). \subsection{On HPUX I get device lan0 open: recv\_ack: promisc\_phys: Invalid argument} It's because there's another program running using the DLPI service. The HP-UX implementation doesn't allow more than one libpcap program at a time to run, unlike Linux (from snort.c). \subsection{Snort is dying with a `can not create file' error and I have plenty of diskspace. What's wrong?} You may run out of free inodes, which basically also means you can not create more files on the partition. The obvious solution is to rm some. ;-) \subsection{I am using Snort on Windows and receive an ``OpenPcap() error upon startup: ERROR: OpenPcap() device open: Error opening adapter'' message. What's wrong? } Either winpcap is not installed, or you are using an incompatible version. Try upgrading to the latest version (2.3 as of 01/17/03). It is available from \htmladdnormallink{http://netgroup-serv.polito.it/winpcap/}{http://netgroup-serv.polito.it/winpcap/}. It might also be an issue with SMP machines \myref{winpcap}. \subsection{Snort is not logging to my database} There are a number of problems that may be causing Snort to fail to log to a database. You should check these: \begin{enumerate} \item You did not set up the database plugin in your configuration file. \item You are using an older database schema, and should update it by running the create scripts from the ./schemas directory of the source tarball. \item You are using a command line option that overrides what you have in your configuration file. This is most often -A or -s. NOTE: If you wish to log to syslog as well, specify so in your configuration file rather then the command line. \item There is a problem with your database configuration itself. Make sure the user you specify has the correct permissions, or that the database is even up and running. \end{enumerate} \subsection{Portscans are not being logged to my database } You need to change the output facility to 'alert' rather then 'log'. The portscan preprocessor calls output plugins registered as 'alert' plugins rather then 'log'. \begin{verbatim}output database: alert, mysql, user=snort dbname=snort host=localhost\end{verbatim} \subsection{Snort is not logging to syslog} There are a number of problems that may be causing snort to fail to log to syslog. You should check these: \begin{itemize} \item You are using a command line option that overrides what you have in your configuration file. This is most often -A. \item It may be logging to the wrong place. Make sure syslog is configured correctly. \end{itemize} \subsection{I am still getting bombarded with spp\_portscan messages even though the IP that I am getting the portscan from is in my \$DNS\_SERVERs var } Try adding /32 netmasks to those addresses: \begin{verbatim}var DNS_SERVERS \[xxx.xx.0.3/32,xxx.xxx.0.2/32\]\end{verbatim} And make sure the \$DNS\_SERVERS variable is on the portscan-ignorehosts line: \begin{verbatim}preprocessor portscan-ignorehosts: $DNS_SERVERS\end{verbatim} \subsection{Why does chrooted Snort die when I send it a SIGHUP? \label{chroot}} It's a known problem with permissions. Workaround, restart snort instead. But the short answer is this: Due to the way the execv(2) call works, it "Restarts" snort from scratch. This has the odd side effect of making HUPS to a chrooted snort become recursive. For example, chroot to /snort. It now sees /snort as / . Now HUP snort. Snort now expects to have /snort/snort as /. In other words, you have to re-create your directories for your jail inside it. 4 HUPS and you will be in /snort/snort/snort/snort. \subsection{My snort crashes, how do I restart it?} Try one of these two shell scripts or daemontools (refer to website to daemontools) \begin{verbatim} * []#!/bin/sh #snorthup: Snort Restarter and Crash Logger #(dr@kyx..net with help from kmaxwell@superpages.com) $conf = "snort.conf" for $IFACE in fxp0 fxp1 do if [ -f /var/run/snort_$IFACE.pid ]; then if ! ps -p `cat /var/run/snort_$IFACE.pid` > /dev/null ; then /usr/bin/logger -p user.notice snorthup: removing bogus pidfile /usr/bin/ logger -p user.notice snorthup: restarting absentee snort o n $IFACE with conf file $i rm -f /var/run/snort_$IFACE.pid /usr/local/bin/snort -D -c $conf -i $IFACE fi; else /usr/bin/ logger -p user.notice snorthup: restarting snort on $IFACE with conf file $conf /usr/local/bin/snort -D -c $conf -i $IFACE fi done \end{verbatim} Another version: \begin{verbatim} * []#!/bin/ksh # snortstartd: Snort (Re)Starter # Dom De Vitto (dom@devitto..com) # (original idea by dr@kyx..net & kmaxwell@superpages.com) # # Note: You'd better get CONF and INTERFACES right or # this script will just keep trying to start snort. # Path to echo, sed, test, ps, grep, logger, rm, and sleep. PATH=$PATH:/usr/bin:/usr/local/bin ; export PATH # Point this to your conf file: CONF="/usr/local/share/examples/snort/snort.conf" # Which interfaces should Snort run on, e.g.: INTERFACES="hme0 hme1" # Wait this many seconds between checks: CHECKEVERY=5 # Full path to Snort: SNORTBINARY=/usr/local/bin/snort while :; do for INT in $INTERFACES do GREPSTRING="`echo $SNORTBINARY -N -D -c $CONF -i $INT|sed 's?\/?\\\/?g'`" PSCMDLINES=`(ps augxww 2>/dev/null||ps -ef 2>/dev/null) | grep "$GREPSTRING"|wc -l` if [ $PSCMDLINES = 0 ]; then logger -p user.notice -t "$0" "Starting Snort on $INT." $SNORTBINARY -N -D -c $CONF -i $INT 2>&1 > /dev/null fi done sleep $CHECKEVERY done \end{verbatim} \subsection{Why can't snort see one of the 10Mbps or 100Mbps traffic on my autoswitch hub?} Basically it's a function of the design and all autoswitching hubs will behave in this way. It's the result of just not being able to stuff all the 100 Mbps traffic into the 10Mbps CSMA/CD. One solution I use to the problem is these new cheapie four port switches... put all the 10Mbps on it's own hub/switch/whatever and then route that to the 100Mbps hub I use for monitoring but put a cheapie switch in between that works as an adapter basically mediating the 10 up to 100 and vice versa. The bad thing about hubs that {\em don't} have this ``feature,'' is that in order to support 10bt devices, they throttle the entire hub speed down to 10bt if there is one or more 10bt only devices hooked up to it. I have seen this behavior (and did the bandwidth tests to prove it) on old 3com office connect 10/100 hubs (newer ones do the 2 hubs with a switch thing.) So, the point of what I am saying is, since these old hubs have no switching capabilities, and they don't know which port the traffic is supposed to go to (no switch=no arp table), they have to throttle bandwidth. None of the hubs and switches have any significant amount of storage on the ethernet chip sets, and therefore {\em any} non-layer-three box that has 100 $->$ 10 capability can only handle small amounts of traffic before the chip set drops incoming packets on the floor. Guess one might call that throttled bandwidth, but at the expense of retransmission timeouts and retransmissions at the end nodes. If the box has a backplane, multiple cards and some network management functions, there is a higher {\em probability} the manufacturer has some additional buffering going on to keep dropped packets from happening on at least small bursts of traffic. In the most generic of terms, if a box supports 100 ``full-duplex,'' then its a switch (regardless of what the manufacturer calls it). If it supports 100 $->$ 10, there is 50-50 chance the box has some MAC address awareness. If a box only supports 10 $->$ 10 or 100 $->$ 100, there is a high probability it is not MAC address aware and therefore functions like a hub. Many hubs have different back planes, i.e., one for 10 and one for 100. >From a definition standpoint, a hub segment whether it be 10 or 100 is a single broadcast/collision domain. You will not see ANY traffic between segements without a bridge or layer3 route function between them. In a switched environment, typically each port is a separate collision domain but one big broadcast domain. VLANs can be created in some to separate into separate broadcast domains and some have built in layer 3 functionality which basically connects a router into the backplane so that it can route between vlans at wire speed. Think of a switch as a bridge with many ports. (that's what it is). Some switches support port mirroring or span ports. When you want to ``sniff'' frames in a switched environment (beyond just broadcast/multicast traffic) you need to be able to "see" the unicast traffic (telnet,http for example). You set up a port to mirror traffic from the ports that have the devices your interested in to the port you have your analysis device plugged into. Without doing so, you don't see the unicast conversations because the traffic is getting "switched" across the backplane so pc on port 1 talks to server on port 2 and no other ports get this traffic. If server on port 2 broadcasts or multicasts, the information is flooded out all ports. (multicast can be controlled on some switches so only those ports that have listening stations get the traffic. Not all switches have these capabilities. An excellent book on the topic is Interconnections by Radia Perlman. (Bridges and Routers). Additional caveat: if you deal with full duplex on a switched port, only a tap would save you - users have successfully used Shomiti's ones on 100MB FD ports, and used two Snort instances, capturing traffic on both directions. Port mirroring didn't work in that case ... \subsection{Trying to install snort it says: ``bad interpreter: No such file or directory''} Usually this error comes from editing files on Windows machines. Often it shows up on the ./configure step. The configure script should be looking for the /bin /sh shell as its interpreter. If /bin/sh doesn't exist then you'll get this error. Check that whatever comes after the \#! on the first line of configure is actually there. If the file has been edited on a Windows machine it can sometimes Add CR/LF (VM) characters on the end of each line, so \#!/bin/sh becomes \#!/bin/shVM and as the ctrl-v/ctrl-m characters are special, and hidden by default on most editors, it can create a really hard to find problem. To remove the extra CR characters that UNIXish machines don't like, simply use the dos2unix command: \begin{verbatim} * []dos2unix \end{verbatim} If your OS doesn't have dos2unix, then you can use: \begin{verbatim} * []cat | tr -d ``\r'' > \end{verbatim} \subsection{I'm not seeing any interfaces listed under Win32.} The reason you're seeing nothing in the interface list is a WinPcap problem. In previous versions of WinPcap there is a 1K buffer, which overflows if you have many interfaces (i.e., 10+). This has been replaced with an 8K buffer in more recent versions of WinPcap. The current snort distribution should already be linking against the newer WinPcap libraries, which should resolve this problem. Try obtaining a more recent build of snort. \subsection{It's not working on Win32, how can I tell if my problem is Snort or WinPcap?} See if WinDump will work with WinPcap. This should help you isolate which component is being bogus. \subsection{I just downloaded a new ruleset and now Snort fails, complaining about the rules.} First, make sure you downloaded the right ruleset for your version of snort. Snort.org generally hosts a ruleset for the released version of Snort, as well as rules for the development branch and sometimes copies for older versions of snort. This is generally the case for ``unknown keyword in rule'' type errors. If you have the rules that are correct for your version of snort be aware that the snort rules tarball contains a snort.conf file. From time to time the snort.conf included with the rules gets changed as new .rules files are added, and new variables are added to support a better ruleset. When downloading new rulesets you should always give the included snort.conf a quick look-over to see if new includes or vars have been added, or at least be aware you should consult it if things do not work as expected. This is generally the case if you get messages indicating that something is undefined in a rule. \subsection{Why am I seeing so many ``SMTP RCPT TO overflow'' alerts ?} That rule looks for a TCP frame going to your SMTP server which contains more than 800 bytes of data. Any email can easily set that off if pipelining is used. SMTP command pipelining allows several command lines lines to be sent as a single packet without waiting for an OK response. Any good high-volume mailserver will try to pipeline where possible, resulting in a single TCP frame containing a series of command lines, each of which is not very long, but in aggregate easily exceed the 800 byte threshold, particularly if there is a large recipient list. For more info on pipelining: \htmladdnormallink{http://www.faqs.org/rfcs/rfc1854.html}{http://www.faqs.org/rfcs/rfc1854.html} If your mailservers are not vulnerable to these overflows you can disable this rule and regain some peace... \subsection{I'm getting lots of *ICMP Ping Speedera*, is this bad?} Quite ordinary. Windows update uses speedera based DNS, among other things. Of course, if the speedera traffic is coming from a Dialup account (as there have been reports of) it's likely a hacker tool. ;-) \subsection{Why are my unified alert times off by +/- N hours?} Unified log and alert files are stored in UTC. \subsection{I try to start Snort and it gives an error like ``ERROR: Unable to open rules file: /root/.snortrc or /root//root/.snortrc.'' What can I do to fix this?} When Snort starts, it looks at the command line and checks for ``-c /some/path/ snort.conf.'' If thats not there, then it will look for the one of the following files: \begin{itemize} \item /etc/snort.conf \item ./snort.conf \item \$HOMEDIR/snort.conf \item \$HOMEDIR/.snortrc \item ./.snortrc \end{itemize} Make sure your .conf is in one of those locations and then Snort will be able to find it or use the -c parameter to tell Snort the full pathname to the snort.conf. \begin{verbatim} snort -c /usr/local/etc/snort.conf \end{verbatim} \subsection{Snort fails to respond to a kill signal on Linux. Why?} In Snort 2.6, a change was made to switch from performing the Snort shutdown function within the signal handlers. This was done to remove reentrant code from the signal handlers, and the vulnerabilities that entailed. The signal handler now simply sets a flag and returns. Snort now uses pcap\_dispatch() with a read timeout value. So, when a signal is received when snort is waiting for packets, the signal handler sets the flag and goes back to waiting for a packet. If the timeout is then reached, pcap\_dispatch() returns and Snort sees it received a signal to exit and exits cleanly. Per the pcap(3) man page, ``Not all platforms support a read timeout; on platforms that don't, the read timeout is ignored.'' Linux is one of the systems where this is not currently supported. Snort does receive the signal, but until a packet arrives, it does not get the chance to exit cleanly. There have been a number of patches created to implement the timeout on linux, and one example can be found here. \htmladdnormallink{http://www.ethereal.com/lists/ethereal-dev/199812/msg00019.html}{http://www.ethereal.com/lists/ethereal-dev/199812/msg00019.html} \subsection{A Rule with PCRE causes a failure to load snort.conf. Why?} Newer Snort rules are using PCRE named expressions (also known as named captures). PCRE only supports this with versions 4.0 and later, and if an earlier version of libpcre is being used, Snort will print the following error at startup. \begin{verbatim} unrecognized character after (? Fatal Error, Quitting.. \end{verbatim} A rule that may cause this problem is shown. \begin{verbatim} alert tcp $EXTERNAL_NET $HTTP_PORTS -> $HOME_NET any (msg:"WEB-CLIENT Microsoft Agent v1.5 ActiveX clsid access"; flow:established,to_client; content:"F5BE8BD2-7DE6-11D0-91FE-00C04FD701A5"; nocase; pcre:"/]*\s*classid\s*=\s*(?P\x22|\x27|)\s*clsid\s*\x3a\s* {?\s*F5BE8BD2-7DE6-11D0-91FE-00C04FD701A5\s*}?\s*(?P=q1)(\s|>)/si"; reference:cve,2005-1214; reference:cve,2006-3445; reference:cve,2007-1205; reference:url,www.microsoft.com/technet/security/bulletin/MS05-032.mspx; reference:url,www.microsoft.com/technet/security/bulletin/MS06-068.mspx; reference:url,www.microsoft.com/technet/security/bulletin/MS07-020.mspx; classtype:attempted-user; sid:4172; rev:3;) \end{verbatim} As of Snort 2.7.0, the minimum version of libpcre is 4.0. Because of various performance improvements and bug fixes within libpcre, it is recommended that Snort be compiled with libpcre version 7.0 or later. Visit \htmladdnormallink{http://www.pcre.org}{http://www.pcre.org} for details. \section{Development} \subsection{How do you put Snort in debug mode? } In Snort 1.9 or higher, \begin{enumerate} \item ./configure --enable-debug \item Look up the sections of Snort you'd like to debug ( look at src/snort\_debug.h ) and bitwise-or the flags together to create a hex value. For example, \begin{verbatim} #define DEBUG_PARSER 0x00000002 ... #define DEBUG_PATTERN_MATCH 0x00001000 \end{verbatim} To debug just the parser: \begin{verbatim} export SNORT_DEBUG=0x2 \end{verbatim} To debug both the parser and pattern matcher: \begin{verbatim} export SNORT_DEBUG=0x1002 \end{verbatim} Debugging preprocessors is similar, eg to debug frag3: \begin{verbatim} export SNORT_PP_DEBUG=0x1 \end{verbatim} \item Run snort as normal. You will need to redirect output to a file to cope with the large amounts of debug output. \end{enumerate} \section{Miscellaneous} \subsection{What's this about a Snort drinking game?} :-) Check it out for yourself: \htmladdnormallink{http://www.theadamsfamily.net/~erek/snort/drinking\_game.txt}{http://www.theadamsfamily.net/~erek/snort/drinking_game.txt} %\begin{thebibliography} %\bibitem[cite74] %\end{thebibliography} \end{document} geany-2.0/tests/ctags/gdscript-no-implicit-class.gd.tags0000644000175000017500000000242714514252267020274 00000000000000ANOTHER_THINGÌ16384ÎNamedÖ0 variable: Named :: ANOTHER_THING ANSWERÌ16384Ö0 variable: ANSWER MyClassÌ1Ö0 class: MyClass NamedÌ2Ö0 enum: Named SomethingÌ1Ö0 class: Something THE_NAMEÌ16384Ö0ÏString variable: String THE_NAME THING_1Ì16384ÎNamedÖ0 variable: Named :: THING_1 THING_2Ì16384ÎNamedÖ0 variable: Named :: THING_2 UNIT_ALLÌ16384Îanon_enum_1Ö0 variable: anon_enum_1 :: UNIT_ALL UNIT_ENEMYÌ16384Îanon_enum_1Ö0 variable: anon_enum_1 :: UNIT_ENEMY UNIT_NEUTRALÌ16384Îanon_enum_1Ö0 variable: anon_enum_1 :: UNIT_NEUTRAL _initÌ128Í()Ö0 method: _init() _private_varÌ16384ÎSomethingÖ0ÏString variable: String Something :: _private_var aÌ16384Ö0 variable: a aÌ16384ÎSomethingÖ0 variable: Something :: a anon_enum_1Ì2Ö1 enum: anon_enum_1 flags: 1 arrÌ16384Ö0 variable: arr dictÌ16384Ö0 variable: dict fooooooooÌ128Í()ÎSomethingÖ0ÏString method: String Something :: foooooooo() inferred_typeÌ16384Ö0 variable: inferred_type sÌ16384Ö0 variable: s sigÌ16384Ö0 variable: sig some_functionÌ128Í(param1: Vector3, param2: int)Ö0Ïint method: int some_function(param1: Vector3, param2: int) somethingÌ128Í(p1, p2)Ö0 method: something(p1, p2) typed_varÌ16384Ö0Ïint variable: int typed_var v2Ì16384Ö0 variable: v2 v3Ì16384Ö0 variable: v3 geany-2.0/tests/ctags/bug814263.java.tags0000644000175000017500000000023014514252267014712 00000000000000bug814263Ì1Ö0 class: bug814263 map1Ì8Îbug814263Ö0Ïjava field: java bug814263 :: map1 map2Ì8Îbug814263Ö0ÏMap field: Map bug814263 :: map2 geany-2.0/tests/ctags/bug2888482.js0000644000175000017500000000067214514252267013562 00000000000000function scrollEditBox() { var editBoxEl = document.getElementById("wpTextbox1"); var scrollTopEl = document.getElementById("wpScrolltop"); var editFormEl = document.getElementById("editform"); if (editBoxEl && scrollTopEl) { if (scrollTopEl.value) editBoxEl.scrollTop = scrollTopEl.value; editFormEl.onsubmit = function() { document.getElementById("wpScrolltop").value = document.getElementById("wpTextbox1").scrollTop; } } } geany-2.0/tests/ctags/py_constructor_arglist.py0000644000175000017500000000222014514252267017042 00000000000000""" Test arglist parsing of a class' __init__ method: the __init__() method's argument list should be assigned to the class' argument list. This is somewhat special to Python and the Python parses uses tm_source_file_set_tag_arglist() to do this and tm_source_file_set_tag_arglist() uses tm_tags_find() which by default relies on a sorted tags array. However, when the parses uses tm_source_file_set_tag_arglist() the tags array is *not yet* sorted and so it might be the tag for the class SomeClass can't be found, hence this test. """ from bsddb import btopen import sys from django.contrib.auth.decorators import login_required, permission_required from django.http import HttpResponse, HttpResponseBadRequest from django.shortcuts import render_to_response from django.template.context import RequestContext from django.utils import simplejson from django.views.decorators.csrf import csrf_exempt from django.views.decorators.csrf import csrf_exempt2 from django.views.decorators.http import require_POST from vnstat.api.error import InterfaceDataValidationError class SomeClass(object): def __init__(self, filename, pathsep='', treegap=64): pass geany-2.0/tests/ctags/bug507864.c0000644000175000017500000000014214514252267013266 00000000000000FUNCSTS func1(ENTSEQNO(seq)) {} FUNCSTS func2 (MEMTXT(form_msg), MEMTXT (text), MEMTXT (mail)) {} geany-2.0/tests/ctags/bug1611054.cs0000644000175000017500000000016014514252267013515 00000000000000class C { public String a() { return @"c:\"; } // this tag is missing in ctags 5.6 public void b() { } } geany-2.0/tests/ctags/cxx14-combined.cpp.tags0000644000175000017500000000035714514252267016045 00000000000000BaseÌ2048Ö0 struct: Base FooÌ2048Ö0 struct: Foo barÌ16Í()ÎFooÖ0Ïauto function: auto Foo :: bar() bazÌ1024Í() constÎBaseÖ0Ïvoid prototype: void Base :: baz() const bazÌ1024Í() constÎFooÖ0Ïvoid prototype: void Foo :: baz() const geany-2.0/tests/ctags/whitespaces.php0000644000175000017500000000046614514252267014710 00000000000000 bool: if sealed: return false if not server.has_peer(peer_id): return false var new_peer: WebSocketPeer = server.get_peer(peer_id) new_peer.put_packet(("I: %d\n" % (1 if peer_id == host else peer_id)).to_utf8()) for p in peers: if not server.has_peer(p): continue server.get_peer(p).put_packet(("N: %d\n" % peer_id).to_utf8()) new_peer.put_packet(("N: %d\n" % (1 if p == host else p)).to_utf8()) peers.push_back(peer_id) return true func leave(peer_id, server) -> bool: if not peers.has(peer_id): return false peers.erase(peer_id) var close = false if peer_id == host: # The room host disconnected, will disconnect all peers. close = true if sealed: return close # Notify other peers. for p in peers: if not server.has_peer(p): return close if close: # Disconnect peers. server.disconnect_peer(p) else: # Notify disconnection. server.get_peer(p).put_packet(("D: %d\n" % peer_id).to_utf8()) return close func seal(peer_id, server) -> bool: # Only host can seal the room. if host != peer_id: return false sealed = true for p in peers: server.get_peer(p).put_packet("S: \n".to_utf8()) time = OS.get_ticks_msec() return true # Taken from godot-demo-projects/2d/physics_tests/test.gd class Circle2D: extends Node2D var center var radius var color func _draw(): draw_circle(center, radius, color) func _init(): server.connect("data_received", self, "_on_data") server.connect("client_connected", self, "_peer_connected") server.connect("client_disconnected", self, "_peer_disconnected") # ... geany-2.0/tests/ctags/indexer.cs0000644000175000017500000000140514514252267013637 00000000000000// cs_keyword_indexers.cs using System; class IndexerClass { private int [] myArray = new int[100]; public int this [int index] // indexer declaration { get { // Check the index limits if (index < 0 || index >= 100) return 0; else return myArray[index]; } set { if (!(index < 0 || index >= 100)) myArray[index] = value; } } } public class MainClass { public static void Main() { IndexerClass b = new IndexerClass(); // call the indexer to initialize the elements #3 and #5: b[3] = 256; b[5] = 1024; for (int i=0; i<=10; i++) { Console.WriteLine("Element #{0} = {1}", i, b[i]); } } } geany-2.0/tests/ctags/bug2075402.py0000644000175000017500000000002214514252267013537 00000000000000y = 1 # """ x = 2 geany-2.0/tests/ctags/simple.tcl.tags0000644000175000017500000000066414514252267014612 00000000000000AÌ256Ö0 namespace: A A::BÌ256Ö0 namespace: A::B CÌ256ÎAÖ0 namespace: A :: C XÌ1Ö0 class: X addÌ64ÎXÖ0 member: X :: add doSomethingÌ64ÎXÖ0 member: X :: doSomething pr1Ì16Í{s}ÎAÖ0 function: A :: pr1{s} pr2Ì16Í{s}ÎBÖ0 function: B :: pr2{s} pr3Ì16Í{s}ÎA::CÖ0 function: A::C :: pr3{s} pr4Ì16Í{s}Ö0 function: pr4{s} pr5Ì16Í{s}Ö0 function: pr5{s} pr6Ì16Í{s}Ö0 function: pr6{s} simple1Ì16Í{}Ö0 function: simple1{} geany-2.0/tests/ctags/gdscript-modifiers.gd.tags0000644000175000017500000000042114514252267016716 00000000000000_create_block_colliderÌ128Í(block_sub_position)Ö0 method: _create_block_collider(block_sub_position) calculate_block_uvsÌ128Í(block_id)Ö0 method: calculate_block_uvs(block_id) idÌ128Í(a)Ö0 method: id(a) rÌ128Í(b)Ö0 method: r(b) xÌ128Í(c)Ö0 method: x(c) geany-2.0/tests/ctags/simple.mak0000644000175000017500000000042114514252267013632 00000000000000A = 1 B := 2 define C 3 endef a.o: D = 4 E = 5 b.o: ENV_VAR1=something command $(obj)/raid6int1.c: F := 6 default: ENV_VAR2=something command # COMMENT = nada G = 7 # ignore comment H = $(A:.y=.c) ${B:.l=.c} export I = 8 NO_TAG1 += \ -DA=0x00000000L \ -DB=0x00000000L geany-2.0/tests/ctags/bug565813.f90.tags0000644000175000017500000000061014514252267014375 00000000000000NÌ16384Îctags_bugÖ0 variable: ctags_bug :: N barÌ64Îfoo_tÖ0 member: foo_t :: bar ctags_bugÌ256Ö0 namespace: ctags_bug foo_getbarÌ16Îctags_bugÖ0 function: ctags_bug :: foo_getbar foo_set_barÌ128Í(f, b)Îctags_bugÖ0 method: ctags_bug :: foo_set_bar(f, b) foo_setbarÌ128Í(f, b)Îctags_bugÖ0 method: ctags_bug :: foo_setbar(f, b) foo_tÌ1Îctags_bugÖ0 class: ctags_bug :: foo_t geany-2.0/tests/ctags/attributes.cs0000644000175000017500000000120614514252267014366 00000000000000[DllImport] public class MyDllimportClass {} [DllImport("user32.dll", SetLastError=false, ExactSpelling=false)] [DllImport("user32.dll", ExactSpelling=false, SetLastError=false)] [DllImport("user32.dll")] [Conditional("DEBUG"), Conditional("TEST1")] void TraceMethod() {} using System; [AttributeUsage(AttributeTargets.Class|AttributeTargets.Struct)] public class Author : Attribute { public Author(string name) { this.name = name; version = 1.0; } public double version; string name; } [AttributeUsage(AttributeTargets.Class|AttributeTargets.Struct, AllowMultiple=true)] // multiuse attribute public class Author : Attribute { } geany-2.0/tests/ctags/ingres_procedures.sql.tags0000644000175000017500000000025414514252267017053 00000000000000db0001Ì256Ö0 namespace: db0001 db0002Ì256Ö0 namespace: db0002 db0003Ì256Ö0 namespace: db0003 errÌ16384Ö0 variable: err nÌ16384Ö0 variable: n xÌ16384Ö0 variable: x geany-2.0/tests/ctags/css-pseudo-classes.css0000644000175000017500000000073514514252267016111 00000000000000 tr:nth-child(2n+1) { background-color: light-gray } tr:nth-child(odd) { background-color: light-gray } tr:nth-child(2n) { background-color: light-gray } tr:nth-child(even) { background-color: light-gray } tr:nth-child(10n+0) { background-color: gray } span:nth-child(0n+1) { color: lime; } span:nth-child(1) { color: lime; } span:nth-child(-n+3) { color: lime; } span:not(:first-child) { color: red; } body :not(span) { color: green; } a:lang(en):after { content: "[en]" } geany-2.0/tests/ctags/qualified_types.f900000644000175000017500000000101514514252267015356 00000000000000module test implicit none type goodtype(p1, p2, p3, p4) ! the stuff in brackets after the name of the type shouldn't appear in the type's name ! this is already correctly handled, so that's fine integer, kind :: p1, p3 ! the question is whether or not these "kind" and "len"s should be shown as members integer, len :: p2, p4 real(kind=p1) :: c1 character(len=p2) :: c2 complex :: c3(p3) integer :: c4 = p1 contains end module test geany-2.0/tests/ctags/backslashes.c0000644000175000017500000000066114514252267014304 00000000000000typedef int T; int func1(\ int var1, int var2, ...); int func2(int var1, \ int var2, ...); int func3(T \ var1, T var2, ...); int func4(T var1, \ T var2, ...); int func5(int \ var1, int var2, ...); // check continuations in macros are properly handled #define MACRO1 \ ( int func6(void); #define MACRO2(x) \ int x(void); #define MACRO3(y) \ int \ y \ ( \ void \ ); int func7(int a); geany-2.0/tests/ctags/c-digraphs.c0000644000175000017500000000105014514252267014033 00000000000000 /* simple trigraphs */ %:define A 1 %:define B 2 %:define STRINGIFY_INTERN(x) %:x %:define STRINGIFY(x) STRINGIFY_INTERN(x) %:define M3_INIT(a, b, c) <% a, b, c %> typedef int matrix3<:3:>; struct str <% char *buf; unsigned int len, size; %>; int main(void) <% const char *hello = STRINGIFY(hello); matrix3 m = M3_INIT(1, 2, 3); return m<:2:>; %> %:if 0 #define bug4 %:endif /* test the same with untaken preprocessor paths (as they are then not read by * the C parser but get.c) */ #if 0 %:define if0d_A 1 %:define if0d_B 2 #endif geany-2.0/tests/ctags/var-and-return-type.cpp.tags0000644000175000017500000000220714514252267017140 00000000000000func1Ì1024Í()Ö0Ïconst volatile unsigned int prototype: const volatile unsigned int func1() func2Ì1024Í()Ö0Ïconst struct type1 prototype: const struct type1 func2() func3Ì1024Í()Ö0Ïconst type1_t prototype: const type1_t func3() func4Ì1024Í()Ö0Ïtype1 prototype: type1 func4() func5Ì1024Í()Ö0Ïtype1_t prototype: type1_t func5() func6Ì1024Í()Ö0Ïconst std::string prototype: const std::string func6() func7Ì1024Í()Ö0Ïstd::string prototype: std::string func7() memb1Ì64Îtype1Ö0Ïunsigned int member: unsigned int type1 :: memb1 nextÌ64Îtype1Ö0Ïtype1 * member: type1 * type1 :: next type1Ì2048Ö0 struct: type1 type1_tÌ4096Ö0Ïtype1 typedef: type1 type1_t type2_tÌ4096Ö0Ïunsigned long int typedef: unsigned long int type2_t var1Ì16384Ö0Ïconst volatile unsigned int variable: const volatile unsigned int var1 var2Ì16384Ö0Ïconst struct type1 variable: const struct type1 var2 var3Ì16384Ö0Ïconst type1_t variable: const type1_t var3 var4Ì16384Ö0Ïtype1 variable: type1 var4 var5Ì16384Ö0Ïtype1_t variable: type1_t var5 var6Ì16384Ö0Ïconst std::string variable: const std::string var6 var7Ì16384Ö0Ïstd::string variable: std::string var7 geany-2.0/tests/ctags/bug858165.f900000644000175000017500000000145114514252267013451 00000000000000! Bugs item #858165, was opened at 2003-12-11 10:09 ! Message generated for change (Tracker Item Submitted) made by Item Submitter ! You can respond by visiting: ! https://sourceforge.net/tracker/?func=detail&atid=106556&aid=858165&group_id=6556 ! ! Category: None ! Group: None ! Status: Open ! Resolution: None ! Priority: 5 ! Submitted By: Blazej Krzeminski (blazk) ! Assigned to: Nobody/Anonymous (nobody) ! Summary: Fortran90: comment line after continuation character & ! ! Initial Comment: program test integer :: a, & !comment on variable a b, & !comment on variable b !more comment on variable b, CTAGS STOPS HERE c, & !comment on variable c d !comment on variable d end program test ! ctags will index program test, a,b but not c,d geany-2.0/tests/ctags/bug1491666.c.tags0000644000175000017500000000030514514252267014307 00000000000000mainÌ16Í(void)Ö0Ïvoid function: void main(void) my_structÌ2048Ö0 struct: my_struct xÌ64Îmy_structÖ0Ïint member: int my_struct :: x yÌ64Îmy_structÖ0Ïfloat member: float my_struct :: y geany-2.0/tests/ctags/sample.t2t.tags0000644000175000017500000000145314514252267014526 00000000000000BeautifiersÌ64ÎFonts and BeautifiersÖ0 member: Fonts and Beautifiers :: Beautifiers Definition ListÌ64ÎListsÖ0 member: Lists :: Definition List Fonts and BeautifiersÌ64Ö0 member: Fonts and Beautifiers ImagesÌ64ÎSpecial EntitiesÖ0 member: Special Entities :: Images IntroductionÌ64Ö0 member: Introduction ListsÌ64Ö0 member: Lists More CosmeticsÌ64ÎFonts and BeautifiersÖ0 member: Fonts and Beautifiers :: More Cosmetics Numbered ListÌ64ÎListsÖ0 member: Lists :: Numbered List OtherÌ64ÎSpecial EntitiesÖ0 member: Special Entities :: Other Plain ListÌ64ÎListsÖ0 member: Lists :: Plain List Pre-Formatted TextÌ64ÎFonts and BeautifiersÖ0 member: Fonts and Beautifiers :: Pre-Formatted Text Special EntitiesÌ64Ö0 member: Special Entities TablesÌ64Ö0 member: Tables geany-2.0/tests/ctags/js-broken-strings.js0000644000175000017500000000053114514252267015570 00000000000000// this file willfully uses CR-LF line endings to check their handling var s1 = "I'm invalid because not terminated var s2 = "I'm valid, I have a line continuation:\ ; function bug1(){}"; var s3 = "I'm invalid because I'm not terminated either \ var bug2 = 'this is inside the s3 string' var s4 = 'this is a separate, valid string' geany-2.0/tests/ctags/bug872494.cpp.tags0000644000175000017500000000020014514252267014562 00000000000000FooClass2Ì1Ö0 class: FooClass2 TemplClassÌ1Ö0 class: TemplClass iÌ64ÎTemplClassÖ0Ïint member: int TemplClass :: i geany-2.0/tests/ctags/interfaces.f900000644000175000017500000000151614514252267014320 00000000000000module HasInterfaces ! INTERFACE blocks can have names ! usually only used for when overloading, but good practice anyway! interface MyFunc function Func1(arg) integer :: arg end function Func1 function Func2(arg) integer :: arg end function Func2 end interface MyFunc ! without a name we just use a generic one interface subroutine CHEEV(...) ! ... end subroutine CHEEV end interface contains function Func1(arg) integer :: arg, func1 func1 = arg end function Func1 function Func2(arg) integer :: arg, func2 func2 = arg end function Func2 end module HasInterfaces program Main use HasInterfaces ! can also occur in PROGRAMs interface MySubroutine subroutine Sub1(arg) ! ... end subroutine Sub1 end interface MySubroutine end program Main geany-2.0/tests/ctags/size_t_wchar_t_typedef.c0000644000175000017500000000005214514252267016537 00000000000000 typedef int size_t; typedef int wchar_t; geany-2.0/tests/ctags/bug1570779.sql0000644000175000017500000000121514514252267013733 00000000000000-- This should find the "address" column when --sql-types=r is used -- ctags -f - --format=2 --excmd=pattern --fields=nks --sort=no --sql-types=cdfFlLPprstTvieURDVnxy bug1570779.sql -- employees bug1570779.sql /^CREATE TABLE employees ($/;" t line:2 -- employees.id bug1570779.sql /^ id integer NOT NULL,$/;" F line:3 -- employees.name bug1570779.sql /^ name varchar(20),$/;" F line:4 -- employees.address bug1570779.sql /^ address varchar(50),$/;" F line:5 CREATE TABLE employees ( id integer NOT NULL, name varchar(20), address varchar(50), primary key (id) ); geany-2.0/tests/ctags/bug2049723.java.tags0000644000175000017500000000037414514252267015006 00000000000000bug2049723Ì1Ö0 class: bug2049723 m1Ì128Í(String arg)Îbug2049723Ö0Ïpublic void method: public void bug2049723 :: m1(String arg) m2Ì128Í(@Nonnull String arg)Îbug2049723Ö0Ïpublic void method: public void bug2049723 :: m2(@Nonnull String arg) geany-2.0/tests/ctags/non-ascii-ident1.php.tags0000644000175000017500000000025714514252267016366 00000000000000__constructÌ16Í($a, $b)Î×Ö0 function: × :: __construct($a, $b) __toStringÌ16Í()Î×Ö0 function: × :: __toString() rÌ16384Î×Ö0 variable: × :: r ×Ì1Ö0 class: × geany-2.0/tests/ctags/simple.rst0000644000175000017500000000063414514252267013700 00000000000000Chapter 1 ========= Intro text of chapter 1 Section 1.1 ----------- Text of section 1.1 Subsection 1.1.1 **************** Text of subsection 1.1.1 Subsubsection 1.1.1.1 ~~~~~~~~~~~~~~~~~~~~~ Text of subsubsection 1.1.1.1 Section 1.2 ----------- Text of section 1.2 Chapter 2 ========= Intro text of chapter 2 Section 2.1 ----------- Text of section 2.1 Section 2.2 ----------- Text of section 2.2 geany-2.0/tests/ctags/infinite_loop.java.tags0000644000175000017500000000002414514252267016304 00000000000000CÌ1Ö0 class: C geany-2.0/tests/ctags/cython_sample2.pyx0000644000175000017500000000044514514252267015346 00000000000000# -*- cython-mode -*- # test code for cython functionality with complex datatypes import numpy as np cimport numpy as np cpdef np.ndarray[dtype=double, ndim=1] my_fun(np.ndarray[dtype=double, ndim=1] x): cdef np.ndarray[dtype=double, ndim=1, mode="c"] res res = 2*x return res geany-2.0/tests/ctags/ruby-block-call.rb0000644000175000017500000000013514514252267015160 00000000000000 def plop [ 1, 2, 3, 4 ].each do |x| x > 0 end.all? end def nothing puts "nothing" end geany-2.0/tests/ctags/css-simple.css0000644000175000017500000000041614514252267014444 00000000000000 * { padding:0; } html { margin: 0 } .header { font-size: 200%; } #footer { font-size: 80%; } div.magic { /* haha */ text-decoration: blink; } .red { color: red } ul li { padding-left: 1em; } .foo a, .foo b { color: blue; } ul > li > a { font: monospace; } geany-2.0/tests/ctags/bug1764143.h.tags0000644000175000017500000000023414514252267014306 00000000000000arch_resetÌ16Í(char mode)Ö0Ïvoid function: void arch_reset(char mode) omap1_arch_resetÌ16Í(char mode)Ö0Ïvoid function: void omap1_arch_reset(char mode) geany-2.0/tests/ctags/square_parens.f900000644000175000017500000000205614514252267015045 00000000000000module squaretest implicit none type Symmetry integer :: matrix(3,3), iterations end type Symmetry ! make sure F2003 '[]' arrays don't break the symbol list type(Symmetry), parameter :: symmetries(14) = & [ Symmetry(reshape([1,0,0, 0,1,0, 0,0,1], [3,3]),1), & Symmetry(reshape([1,0,0, 0,0,1, 0,-1,0],[3,3]),3), & Symmetry(reshape([0,0,-1, 0,1,0, 1,0,0], [3,3]),3) ] integer :: invisible ! make sure coarray syntax doesn't break the symbol list real, allocatable :: state(:)[:] integer :: invisible_two ! there are multiple ways to specify `dimension` and `codimension` ! a normal dimension and a codimension real, intent(in), allocatable, dimension(:), codimension[:] :: state_two integer :: invisible_three ! a 'normal' scalar (no '()'), but with a codimension '[]' real, allocatable :: assignee[:] integer :: invisible_four contains subroutine execute(state) real, intent(in) :: state(:)[:] end subroutine execute end module squaretest program main use module squaretest end program main geany-2.0/tests/ctags/func_typedef.h.tags0000644000175000017500000000004714514252267015434 00000000000000symlist_tÌ4096Ö0 typedef: symlist_t geany-2.0/tests/ctags/bug612621.pl.tags0000644000175000017500000000006214514252267014401 00000000000000barÌ16Ö0 function: bar fooÌ16Ö0 function: foo geany-2.0/tests/ctags/bug1944150.sql0000644000175000017500000000014614514252267013721 00000000000000CREATE TRIGGER [tr_d_cash_trade_comment] ON dbo.cash_trade_comment FOR DELETE AS BEGIN END GO geany-2.0/tests/ctags/local.c0000644000175000017500000000046514514252267013115 00000000000000main () { int a; int b = 3; a = 2; } static boolean isContextualKeyword (const tokenInfo *const token) { boolean result; label: goto label; switch (token->keyword) { case KEYWORD_UNION: result = TRUE; break; default: result = FALSE; break; } return result; } geany-2.0/tests/ctags/continuation.mak.tags0000644000175000017500000000006014514252267016007 00000000000000AÌ65536Ö0 macro: A BÌ65536Ö0 macro: B geany-2.0/tests/ctags/bug1093123.cpp0000644000175000017500000000012314514252267013672 00000000000000#include int main() { using namespace std; cout << 0 << endl; int m; } geany-2.0/tests/ctags/ada-package-generic.ads0000644000175000017500000000051414514252267016073 00000000000000-- Taken from #2925 submitted by @koenmeersman package My_Package is generic type Num is digits <>; package Conversions is function From_Big_Real (Arg : Integer) return Num; end Conversions; type Missing_Tag is record Num : Integer; end record; type Primary_Color is (Red, Green, Blue); end My_Package; geany-2.0/tests/ctags/spurious_label_tags.c0000644000175000017500000000041614514252267016065 00000000000000/* When run with --c-kinds=+lp option demonstrates spurious tags for statement * following a label */ static void label_forced_tags(void) { label1: proto1(arg); label2: if (arg) proto2(arg); label3: variable = 3; while (condition) { label4: proto3(arg); } } geany-2.0/tests/ctags/format.pl0000644000175000017500000000016214514252267013476 00000000000000# Test format tag generation. format XYZ = @<<< @>>> "1", "a" . format = @>>> 24 . write; $~ = XYZ; write; geany-2.0/tests/ctags/enum.java.tags0000644000175000017500000000100714514252267014414 00000000000000AÌ4ÎeÖ0 enumerator: e :: A BÌ4ÎeÖ0 enumerator: e :: B CÌ4ÎeÖ0 enumerator: e :: C DÌ4ÎeÖ0 enumerator: e :: D EÌ4ÎeÖ0 enumerator: e :: E FÌ4ÎeÖ0 enumerator: e :: F eÌ2Ö0 enum: e getShapeÌ128Í()ÎeÖ0Ïpublic final Shape method: public final Shape e :: getShape() getStringÌ128Í()ÎeÖ0Ïpublic String method: public String e :: getString() shapeÌ8ÎeÖ0ÏShape field: Shape e :: shape stringÌ8ÎeÖ0ÏString field: String e :: string twoKeywordsInARowÌ8ÎeÖ0Ïboolean field: boolean e :: twoKeywordsInARow geany-2.0/tests/ctags/keyword_struct.cs0000644000175000017500000000113014514252267015264 00000000000000// keyword_struct.cs // struct declaration and initialization using System; public struct Point { public int x, y; public Point(int p1, int p2) { x = p1; y = p2; } } class MainClass { public static void Main() { // Initialize: Point myPoint = new Point(); Point yourPoint = new Point(10,10); // Display results: Console.Write("My Point: "); Console.WriteLine("x = {0}, y = {1}", myPoint.x, myPoint.y); Console.Write("Your Point: "); Console.WriteLine("x = {0}, y = {1}", yourPoint.x, yourPoint.y); } } geany-2.0/tests/ctags/bug1988026.py.tags0000644000175000017500000000030714514252267014520 00000000000000im_a_functionÌ16Í()Ö0 function: im_a_function() mainÌ128Í()ÎtestClassÖ0 method: testClass :: main() my_varÌ16384ÎtestClassÖ0 variable: testClass :: my_var testClassÌ1Ö0 class: testClass geany-2.0/tests/ctags/intro.tex.tags0000644000175000017500000000156714514252267014475 00000000000000IntroductionÌ64Îchapter textÖ0 member: chapter text :: Introduction Part1Ì2Ö0 enum: Part1 Part2Ì2Ö0 enum: Part2 chapter textÌ256Ö0 namespace: chapter text chapter2Ì256ÎPart2Ö0 namespace: Part2 :: chapter2 section1 textÌ64Îchapter textÖ0 member: chapter text :: section1 text short section4Ì64ÎPart1Ö0 member: Part1 :: short section4 shorter intro2Ì64ÎPart2Ö0 member: Part2 :: shorter intro2 subsec5 textÌ65536ÎPart2""shorter intro2Ö0 macro: Part2""shorter intro2 :: subsec5 text subsection2Ì65536ÎPart1Ö0 macro: Part1 :: subsection2 subsubsection3 with extra textÌ16384ÎPart1""subsection2Ö0 variable: Part1""subsection2 :: subsubsection3 with extra text subsubsection6 with extra textÌ16384ÎPart2""shorter intro2""subsec5 textÖ0 variable: Part2""shorter intro2""subsec5 text :: subsubsection6 with extra text verbatimÌ1Ö0 class: verbatim geany-2.0/tests/ctags/simple.md.tags0000644000175000017500000000166414514252267014431 00000000000000AÌ256Ö0 namespace: A BÌ256Ö0 namespace: B CÌ256Ö0 namespace: C DÌ64ÎCÖ0 member: C :: D EÌ64ÎCÖ0 member: C :: E FÌ64ÎCÖ0 member: C :: F aÌ256Ö0 namespace: a bÌ64ÎaÖ0 member: a :: b cÌ65536Îa""bÖ0 macro: a""b :: c dÌ16384Îa""b""cÖ0 variable: a""b""c :: d eÌ2048Îa""b""c""dÖ0 struct: a""b""c""d :: e fÌ8192Îa""b""c""d""eÖ0 union: a""b""c""d""e :: f gÌ256Ö0 namespace: g hÌ256Ö0 namespace: h iÌ64ÎhÖ0 member: h :: i jÌ64ÎhÖ0 member: h :: j kÌ64ÎhÖ0 member: h :: k lÌ65536Îh""kÖ0 macro: h""k :: l mÌ65536Îh""kÖ0 macro: h""k :: m nÌ65536Îh""kÖ0 macro: h""k :: n oÌ65536Îh""kÖ0 macro: h""k :: o pÌ16384Îh""k""oÖ0 variable: h""k""o :: p qÌ16384Îh""k""oÖ0 variable: h""k""o :: q rÌ2048Îh""k""o""qÖ0 struct: h""k""o""q :: r sÌ2048Îh""k""o""qÖ0 struct: h""k""o""q :: s tÌ8192Îh""k""o""q""sÖ0 union: h""k""o""q""s :: t uÌ8192Îh""k""o""q""sÖ0 union: h""k""o""q""s :: u geany-2.0/tests/ctags/bug1906062.py0000644000175000017500000000013014514252267013543 00000000000000include_file = ''' class (b) ''' # dummy class to generate a tag class dummy: pass geany-2.0/tests/ctags/simple.docbook.tags0000644000175000017500000000030214514252267015435 00000000000000chapter1Ì16Ö0 function: chapter1 conclusionÌ1Ö0 class: conclusion introÌ1Ö0 class: intro sect1Ì64Ö0 member: sect1 sect2Ì65536Ö0 macro: sect2 sect3Ì16384Ö0 variable: sect3 geany-2.0/tests/ctags/keyword_params.cs.tags0000644000175000017500000000054414514252267016170 00000000000000MainÌ128Í()ÎMyClassÖ0Ïpublic void method: public void MyClass :: Main() MyClassÌ1Ö0 class: MyClass UseParamsÌ128Í(params int[] list)ÎMyClassÖ0Ïpublic void method: public void MyClass :: UseParams(params int[] list) UseParams2Ì128Í(params object[] list)ÎMyClassÖ0Ïpublic void method: public void MyClass :: UseParams2(params object[] list) geany-2.0/tests/ctags/cxx11-noexcept.cpp0000644000175000017500000000020514514252267015142 00000000000000class Base { public: virtual void foo() noexcept = 0; virtual void bar() const noexcept = 0; int baz() noexcept { return 42; } }; geany-2.0/tests/ctags/procedure_pointer_module.f900000644000175000017500000000044314514252267017270 00000000000000! a module that uses procedure pointer module proc_pointer real :: a procedure(sub), pointer :: my_pointer contains subroutine sub(x) real, intent(inout) :: x(:) integer :: i do i=1,size(x) x(i) = 0.5**i end do end subroutine sub end module proc_pointer geany-2.0/tests/ctags/matlab_test.m0000644000175000017500000000035314514252267014330 00000000000000function [x,y,z] = func1 function x = func2 function func3 function y = func4(a, b, c) function func5 % this comment should be ignored --> X = FAIL5 functionality = FAIL6; % this is not a function and should not be parsed geany-2.0/tests/ctags/bug612019.pas.tags0000644000175000017500000000014614514252267014555 00000000000000Test1Ì16Í()Ö0 function: Test1() Test2Ì16Í()Ö0 function: Test2() Test3Ì16Í()Ö0 function: Test3() geany-2.0/tests/ctags/common.f0000644000175000017500000000017614514252267013315 00000000000000 PROGRAM main COMMON /common1/ c1a, c1b COMMON /common2/ c2a (1:3), c2b /common3/ c3a, c3b END geany-2.0/tests/ctags/enum.c0000644000175000017500000000010214514252267012753 00000000000000enum test_enumeration { ENUM_1 = 1, ENUM_2, ENUM_3 }; geany-2.0/tests/ctags/traffic_signal.v0000644000175000017500000000224414514252267015016 00000000000000// http://www.eg.bucknell.edu/~cs320/1995-fall/verilog-manual.html#RTFToC33 // Digital model of a traffic light // By Dan Hyde August 10, 1995 module traffic; parameter on = 1, off = 0, red_tics = 35, amber_tics = 3, green_tics = 20; reg clock, red, amber, green; // will stop the simulation after 1000 time units initial begin: stop_at #1000; $stop; end // initialize the lights and set up monitoring of registers initial begin: Init red = off; amber = off; green = off; $display(" Time green amber red"); $monitor("%3d %b %b %b", $time, green, amber, red); end // task to wait for 'tics' positive edge clocks // before turning light off task light; output color; input [31:0] tics; begin repeat(tics) // wait to detect tics positive edges on clock @(posedge clock); color = off; end endtask // waveform for clock period of 2 time units always begin: clock_wave #1 clock = 0; #1 clock = 1; end always begin: main_process red = on; light(red, red_tics); // call task to wait green = on; light(green, green_tics); amber = on; light(amber, amber_tics); end endmodule geany-2.0/tests/ctags/python-anonymous-nestlevel_ctags-bug-356.py.tags0000644000175000017500000000024614514252267023000 00000000000000TestclassÌ1Ö0 class: Testclass mainÌ128Í(self)ÎTestclassÖ0 method: Testclass :: main(self) module_level_attributeÌ16384Ö0 variable: module_level_attribute geany-2.0/tests/ctags/3526726.tex.tags0000644000175000017500000005426314514252267014201 00000000000000A Rule with PCRE causes a failure to load snort.conf. Why?Ì65536ÎProblemsÖ0 macro: Problems :: A Rule with PCRE causes a failure to load snort.conf. Why? After I add new rules or comment out rules how do I make Snort reload?Ì65536ÎRules and AlertsÖ0 macro: Rules and Alerts :: After I add new rules or comment out rules how do I make Snort reload? Are rule keywords ORed or ANDed together?Ì65536ÎRules and AlertsÖ0 macro: Rules and Alerts :: Are rule keywords ORed or ANDed together? Are there other output systems for Snort besides ``Barnyard''?\label{spoolers}Ì65536ÎGetting FancyÖ0 macro: Getting Fancy :: Are there other output systems for Snort besides ``Barnyard''?\label{spoolers} BASE appears to be broken in LynxÌ65536ÎProblemsÖ0 macro: Problems :: BASE appears to be broken in Lynx BackgroundÌ64Ö0 member: Background Can Snort be evaded by the use of polymorphic mutators on shellcode?Ì65536ÎBackgroundÖ0 macro: Background :: Can Snort be evaded by the use of polymorphic mutators on shellcode? Can Snort trigger a rule by MAC addresses?Ì65536ÎRules and AlertsÖ0 macro: Rules and Alerts :: Can Snort trigger a rule by MAC addresses? Can priorities be assigned to alerts using BASE?Ì65536ÎRules and AlertsÖ0 macro: Rules and Alerts :: Can priorities be assigned to alerts using BASE? Configuring SnortÌ64Ö0 member: Configuring Snort DevelopmentÌ64Ö0 member: Development Does Snort handle IP defragmentation?Ì65536ÎBackgroundÖ0 macro: Background :: Does Snort handle IP defragmentation? Does Snort log the full packets when it generates alerts?Ì65536ÎBackgroundÖ0 macro: Background :: Does Snort log the full packets when it generates alerts? Does Snort perform TCP stream reassembly?Ì65536ÎBackgroundÖ0 macro: Background :: Does Snort perform TCP stream reassembly? Does Snort perform stateful protocol analysis?Ì65536ÎBackgroundÖ0 macro: Background :: Does Snort perform stateful protocol analysis? Does snort see packets filtered by IPTables/IPChains/IPF/PF?Ì65536ÎRules and AlertsÖ0 macro: Rules and Alerts :: Does snort see packets filtered by IPTables/IPChains/IPF/PF? Errors loading rules filesÌ65536ÎRules and AlertsÖ0 macro: Rules and Alerts :: Errors loading rules files Getting FancyÌ64Ö0 member: Getting Fancy Getting StartedÌ64Ö0 member: Getting Started How can I deactivate a rule?Ì65536ÎRules and AlertsÖ0 macro: Rules and Alerts :: How can I deactivate a rule? How can I define an address to be anything except some hosts?Ì65536ÎRules and AlertsÖ0 macro: Rules and Alerts :: How can I define an address to be anything except some hosts? How can I examine logged packets in more detail?Ì65536ÎGetting FancyÖ0 macro: Getting Fancy :: How can I examine logged packets in more detail? How can I protect web servers running on ports other than 80?Ì65536ÎRules and AlertsÖ0 macro: Rules and Alerts :: How can I protect web servers running on ports other than 80? How can I run Snort on multiple interfaces simultaneously?Ì65536ÎConfiguring SnortÖ0 macro: Configuring Snort :: How can I run Snort on multiple interfaces simultaneously? How can I specify a list of ports in a rule?Ì65536ÎRules and AlertsÖ0 macro: Rules and Alerts :: How can I specify a list of ports in a rule? How can I test Snort without having an Ethernet card or a connection to other computers?Ì65536ÎGetting FancyÖ0 macro: Getting Fancy :: How can I test Snort without having an Ethernet card or a connection to other computers? How can I use Snort to log HTTP URLs or SMTP traffic?Ì65536ÎGetting FancyÖ0 macro: Getting Fancy :: How can I use Snort to log HTTP URLs or SMTP traffic? How do I build this BASE thing?Ì65536ÎConfiguring SnortÖ0 macro: Configuring Snort :: How do I build this BASE thing? How do I configure stream4?Ì65536ÎConfiguring SnortÖ0 macro: Configuring Snort :: How do I configure stream4? How do I get Snort and ACID working?Ì65536ÎConfiguring SnortÖ0 macro: Configuring Snort :: How do I get Snort and ACID working? How do I get Snort to e-mail me alerts?Ì65536ÎGetting FancyÖ0 macro: Getting Fancy :: How do I get Snort to e-mail me alerts? How do I get Snort to log the packet payload as well as the header?Ì65536ÎConfiguring SnortÖ0 macro: Configuring Snort :: How do I get Snort to log the packet payload as well as the header? How do I ignore traffic coming from a particular host or hosts?Ì65536ÎConfiguring SnortÖ0 macro: Configuring Snort :: How do I ignore traffic coming from a particular host or hosts? How do I log a specific type of traffic and send alerts to syslog?Ì65536ÎGetting FancyÖ0 macro: Getting Fancy :: How do I log a specific type of traffic and send alerts to syslog? How do I log to multiple databases or output plugins?Ì65536ÎGetting FancyÖ0 macro: Getting Fancy :: How do I log to multiple databases or output plugins? How do I process those Snort logs into reports?Ì65536ÎGetting FancyÖ0 macro: Getting Fancy :: How do I process those Snort logs into reports? How do I run Snort?Ì65536ÎGetting StartedÖ0 macro: Getting Started :: How do I run Snort? How do I set EXTERNAL\_NET?Ì65536ÎConfiguring SnortÖ0 macro: Configuring Snort :: How do I set EXTERNAL\_NET? How do I setup a receive-only ethernet cable?Ì65536ÎConfiguring SnortÖ0 macro: Configuring Snort :: How do I setup a receive-only ethernet cable? How do I setup snort on a `stealth' interface?Ì65536ÎConfiguring SnortÖ0 macro: Configuring Snort :: How do I setup snort on a `stealth' interface? How do I test Snort alerts and logging?Ì65536ÎRules and AlertsÖ0 macro: Rules and Alerts :: How do I test Snort alerts and logging? How do I turn off ``spp:possible EVASIVE RST detection'' alerts?Ì65536ÎRules and AlertsÖ0 macro: Rules and Alerts :: How do I turn off ``spp:possible EVASIVE RST detection'' alerts? How do I understand this traffic and do IDS alert analysis?Ì65536ÎGetting FancyÖ0 macro: Getting Fancy :: How do I understand this traffic and do IDS alert analysis? How do I use a remote syslog machine?Ì65536ÎConfiguring SnortÖ0 macro: Configuring Snort :: How do I use a remote syslog machine? How do you get Snort to ignore some traffic?Ì65536ÎConfiguring SnortÖ0 macro: Configuring Snort :: How do you get Snort to ignore some traffic? How do you pronounce the names of some of these guys who work on Snort?Ì65536ÎBackgroundÖ0 macro: Background :: How do you pronounce the names of some of these guys who work on Snort? How do you put Snort in debug mode?Ì65536ÎDevelopmentÖ0 macro: Development :: How do you put Snort in debug mode? How does rule ordering work?Ì65536ÎConfiguring SnortÖ0 macro: Configuring Snort :: How does rule ordering work? How long can address lists, variables, or rules be?Ì65536ÎRules and AlertsÖ0 macro: Rules and Alerts :: How long can address lists, variables, or rules be? How to start Snort as a win32 service?Ì65536ÎGetting FancyÖ0 macro: Getting Fancy :: How to start Snort as a win32 service? I am getting `snort [pid] uses obsolete (PF\_INET, SOCK\_PACKET)' warnings. What's wrong?Ì65536ÎProblemsÖ0 macro: Problems :: I am getting `snort [pid] uses obsolete (PF\_INET, SOCK\_PACKET)' warnings. What's wrong? I am getting too many ``IIS Unicode attack detected'' and/or ``CGI Null Byte attack detected'' false positives. How can I turn this detection off?Ì65536ÎRules and AlertsÖ0 macro: Rules and Alerts :: I am getting too many ``IIS Unicode attack detected'' and/or ``CGI Null Byte attack detected'' false positives. How can I turn this detection off? I am still getting bombarded with spp\_portscan messages even though the IP that I am getting the portscan from is in my \$DNS\_SERVERs varÌ65536ÎProblemsÖ0 macro: Problems :: I am still getting bombarded with spp\_portscan messages even though the IP that I am getting the portscan from is in my \$DNS\_SERVERs var I am using Snort on Windows and receive an ``OpenPcap() error upon startup: ERROR: OpenPcap() device open: Error opening adapter'' message. What's wrong?Ì65536ÎProblemsÖ0 macro: Problems :: I am using Snort on Windows and receive an ``OpenPcap() error upon startup: ERROR: OpenPcap() device open: Error opening adapter'' message. What's wrong? I have one network card and two aliases, how can I force Snort to ``listen'' on both addresses?Ì65536ÎConfiguring SnortÖ0 macro: Configuring Snort :: I have one network card and two aliases, how can I force Snort to ``listen'' on both addresses? I hear people talking about ``Barnyard''. What's that?\label{barnyard}Ì65536ÎGetting FancyÖ0 macro: Getting Fancy :: I hear people talking about ``Barnyard''. What's that?\label{barnyard} I just downloaded a new ruleset and now Snort fails, complaining about the rules.Ì65536ÎProblemsÖ0 macro: Problems :: I just downloaded a new ruleset and now Snort fails, complaining about the rules. I think I found a bug in Snort. Now what?Ì65536ÎProblemsÖ0 macro: Problems :: I think I found a bug in Snort. Now what? I try to start Snort and it gives an error like ``ERROR: Unable to open rules file: /root/.snortrc or /root//root/.snortrc.'' What can I do to fix this?Ì65536ÎProblemsÖ0 macro: Problems :: I try to start Snort and it gives an error like ``ERROR: Unable to open rules file: /root/.snortrc or /root//root/.snortrc.'' What can I do to fix this? I want to build a Snort box. Will this $<$Insert list of hardware$>$ handle $<$this much$>$ traffic?Ì65536ÎGetting StartedÖ0 macro: Getting Started :: I want to build a Snort box. Will this $<$Insert list of hardware$>$ handle $<$this much$>$ traffic? I'm getting large amounts of $<$some alerts type$>$. What should I do? Where can I go to find out more about it?Ì65536ÎRules and AlertsÖ0 macro: Rules and Alerts :: I'm getting large amounts of $<$some alerts type$>$. What should I do? Where can I go to find out more about it? I'm getting lots of *ICMP Ping Speedera*, is this bad?Ì65536ÎProblemsÖ0 macro: Problems :: I'm getting lots of *ICMP Ping Speedera*, is this bad? I'm not seeing any interfaces listed under Win32.Ì65536ÎProblemsÖ0 macro: Problems :: I'm not seeing any interfaces listed under Win32. I'm on a switched network, can I still use Snort?Ì65536ÎBackgroundÖ0 macro: Background :: I'm on a switched network, can I still use Snort? I've got RedHat and ....Ì65536ÎGetting StartedÖ0 macro: Getting Started :: I've got RedHat and .... IDSCenterÌ2048Ö0 struct: IDSCenter Is Fyodor Yarochkin the same Fyodor who wrote nmap?Ì65536ÎBackgroundÖ0 macro: Background :: Is Fyodor Yarochkin the same Fyodor who wrote nmap? Is Snort vulnerable to IDS noise generators like ``Stick'' and ``Snot''?Ì65536ÎBackgroundÖ0 macro: Background :: Is Snort vulnerable to IDS noise generators like ``Stick'' and ``Snot''? Is it possible to have Snort call an external program when an alert is raised?Ì65536ÎGetting FancyÖ0 macro: Getting Fancy :: Is it possible to have Snort call an external program when an alert is raised? Is it possible with snort to add a ipfilter/ipfw rule to a firewall?Ì65536ÎGetting FancyÖ0 macro: Getting Fancy :: Is it possible with snort to add a ipfilter/ipfw rule to a firewall? Is there a private SID number range so my rules don't conflict?Ì65536ÎRules and AlertsÖ0 macro: Rules and Alerts :: Is there a private SID number range so my rules don't conflict? It's not working on Win32, how can I tell if my problem is Snort or WinPcap?Ì65536ÎProblemsÖ0 macro: Problems :: It's not working on Win32, how can I tell if my problem is Snort or WinPcap? Libpcap complains about permissions problems, what's going on?Ì65536ÎGetting StartedÖ0 macro: Getting Started :: Libpcap complains about permissions problems, what's going on? MiscellaneousÌ64Ö0 member: Miscellaneous My /var/log/snort directory gets very large...Ì65536ÎProblemsÖ0 macro: Problems :: My /var/log/snort directory gets very large... My BASE db connection times-out when performing long operations (e.g. deleting a large number of alerts).Ì65536ÎProblemsÖ0 macro: Problems :: My BASE db connection times-out when performing long operations (e.g. deleting a large number of alerts). My IP address is assigned dynamically to my interface, can I use Snort with it?Ì65536ÎConfiguring SnortÖ0 macro: Configuring Snort :: My IP address is assigned dynamically to my interface, can I use Snort with it? My network spans multiple subnets. How do I define HOME\_NET?Ì65536ÎConfiguring SnortÖ0 macro: Configuring Snort :: My network spans multiple subnets. How do I define HOME\_NET? My snort crashes, how do I restart it?Ì65536ÎProblemsÖ0 macro: Problems :: My snort crashes, how do I restart it? On HPUX I get device lan0 open: recv\_ack: promisc\_phys: Invalid argumentÌ65536ÎProblemsÖ0 macro: Problems :: On HPUX I get device lan0 open: recv\_ack: promisc\_phys: Invalid argument Portscans are not being logged to my databaseÌ65536ÎProblemsÖ0 macro: Problems :: Portscans are not being logged to my database ProblemsÌ64Ö0 member: Problems Rules and AlertsÌ64Ö0 member: Rules and Alerts SMB alerts aren't working, what's wrong?Ì65536ÎProblemsÖ0 macro: Problems :: SMB alerts aren't working, what's wrong? Snort complains about the ``react'' keyword...Ì65536ÎGetting FancyÖ0 macro: Getting Fancy :: Snort complains about the ``react'' keyword... Snort fails to respond to a kill signal on Linux. Why?Ì65536ÎProblemsÖ0 macro: Problems :: Snort fails to respond to a kill signal on Linux. Why? Snort is behind a firewall (ipf/pf/ipchains/ipfilter) and awfully quiet...Ì65536ÎRules and AlertsÖ0 macro: Rules and Alerts :: Snort is behind a firewall (ipf/pf/ipchains/ipfilter) and awfully quiet... Snort is dying with a `can not create file' error and I have plenty of diskspace. What's wrong?Ì65536ÎProblemsÖ0 macro: Problems :: Snort is dying with a `can not create file' error and I have plenty of diskspace. What's wrong? Snort is not logging to my databaseÌ65536ÎProblemsÖ0 macro: Problems :: Snort is not logging to my database Snort is not logging to syslogÌ65536ÎProblemsÖ0 macro: Problems :: Snort is not logging to syslog Snort says BACKDOOR SIGNATURE... does my machine have a Trojan?Ì65536ÎRules and AlertsÖ0 macro: Rules and Alerts :: Snort says BACKDOOR SIGNATURE... does my machine have a Trojan? Snort says ``Garbage Packet with Null Pointer discarded!'' Huh?Ì65536ÎProblemsÖ0 macro: Problems :: Snort says ``Garbage Packet with Null Pointer discarded!'' Huh? Snort says ``Ran Out Of Space.'' Huh?Ì65536ÎProblemsÖ0 macro: Problems :: Snort says ``Ran Out Of Space.'' Huh? Snort says ``Rule IP addr (``1.1.1.1'') didn't x-late, WTF?''Ì65536ÎRules and AlertsÖ0 macro: Rules and Alerts :: Snort says ``Rule IP addr (``1.1.1.1'') didn't x-late, WTF?'' Trying to install snort it says: ``bad interpreter: No such file or directory''Ì65536ÎProblemsÖ0 macro: Problems :: Trying to install snort it says: ``bad interpreter: No such file or directory'' What about `SMB Name Wildcard' alerts?Ì65536ÎRules and AlertsÖ0 macro: Rules and Alerts :: What about `SMB Name Wildcard' alerts? What about ``CGI Null Byte attacks?''Ì65536ÎRules and AlertsÖ0 macro: Rules and Alerts :: What about ``CGI Null Byte attacks?'' What about all these false alarms?Ì65536ÎRules and AlertsÖ0 macro: Rules and Alerts :: What about all these false alarms? What are CIDR netmasks?Ì65536ÎGetting StartedÖ0 macro: Getting Started :: What are CIDR netmasks? What are HOME\_NET and EXTERNAL\_NET?Ì65536ÎConfiguring SnortÖ0 macro: Configuring Snort :: What are HOME\_NET and EXTERNAL\_NET? What are all these ICMP files in subdirectories under /var/log/snort?Ì65536ÎRules and AlertsÖ0 macro: Rules and Alerts :: What are all these ICMP files in subdirectories under /var/log/snort? What are all these ``ICMP destination unreachable'' alerts?Ì65536ÎRules and AlertsÖ0 macro: Rules and Alerts :: What are all these ``ICMP destination unreachable'' alerts? What are some resources that I can use to understand more about source addresses logged and where they are coming from?Ì65536ÎGetting FancyÖ0 macro: Getting Fancy :: What are some resources that I can use to understand more about source addresses logged and where they are coming from? What are these IDS codes in the alert names?Ì65536ÎRules and AlertsÖ0 macro: Rules and Alerts :: What are these IDS codes in the alert names? What do the numbers (ie: [116:56:1]) in front of a Snort alert mean?Ì65536ÎRules and AlertsÖ0 macro: Rules and Alerts :: What do the numbers (ie: [116:56:1]) in front of a Snort alert mean? What is the best way to use Snort to block attack traffic?Ì65536ÎGetting FancyÖ0 macro: Getting Fancy :: What is the best way to use Snort to block attack traffic? What is the difference between ``Alerting'' and ``Logging''?Ì65536ÎRules and AlertsÖ0 macro: Rules and Alerts :: What is the difference between ``Alerting'' and ``Logging''? What is the use of the ``-r'' switch to read tcpdump files?Ì65536ÎGetting StartedÖ0 macro: Getting Started :: What is the use of the ``-r'' switch to read tcpdump files? What the heck is a SYNFIN scan?Ì65536ÎConfiguring SnortÖ0 macro: Configuring Snort :: What the heck is a SYNFIN scan? What the heck is a SYNFIN scan?Ì65536ÎRules and AlertsÖ0 macro: Rules and Alerts :: What the heck is a SYNFIN scan? What the heck is a ``Stealth scan''?Ì65536ÎConfiguring SnortÖ0 macro: Configuring Snort :: What the heck is a ``Stealth scan''? What version of Winpcap do I need?\label{winpcap}Ì65536ÎGetting StartedÖ0 macro: Getting Started :: What version of Winpcap do I need?\label{winpcap} What's this about a Snort drinking game?Ì65536ÎMiscellaneousÖ0 macro: Miscellaneous :: What's this about a Snort drinking game? Where are my log files located? What are they named?Ì65536ÎGetting StartedÖ0 macro: Getting Started :: Where are my log files located? What are they named? Where can I get more reading and courses about IDS?\label{courses}Ì65536ÎBackgroundÖ0 macro: Background :: Where can I get more reading and courses about IDS?\label{courses} Where do I find binary packages for BlueHat BSD-Linux-RT?Ì65536ÎGetting StartedÖ0 macro: Getting Started :: Where do I find binary packages for BlueHat BSD-Linux-RT? Where do I get more help on Snort?Ì65536ÎBackgroundÖ0 macro: Background :: Where do I get more help on Snort? Where do I get the latest version of Winpcap?Ì65536ÎGetting StartedÖ0 macro: Getting Started :: Where do I get the latest version of Winpcap? Where do I get the latest version of libpcap?Ì65536ÎGetting StartedÖ0 macro: Getting Started :: Where do I get the latest version of libpcap? Where do the distance and within keywords work from to modify content searches in rules?Ì65536ÎRules and AlertsÖ0 macro: Rules and Alerts :: Where do the distance and within keywords work from to modify content searches in rules? Where does one obtain new/modifed rules? How do you merge them in?Ì65536ÎConfiguring SnortÖ0 macro: Configuring Snort :: Where does one obtain new/modifed rules? How do you merge them in? Where's a good place to physically put a Snort sensor?Ì65536ÎGetting StartedÖ0 macro: Getting Started :: Where's a good place to physically put a Snort sensor? Which takes precedence, commandline or rule file ?Ì65536ÎConfiguring SnortÖ0 macro: Configuring Snort :: Which takes precedence, commandline or rule file ? Why am I seeing so many ``SMTP RCPT TO overflow'' alerts ?Ì65536ÎProblemsÖ0 macro: Problems :: Why am I seeing so many ``SMTP RCPT TO overflow'' alerts ? Why are my unified alert times off by +/- N hours?Ì65536ÎProblemsÖ0 macro: Problems :: Why are my unified alert times off by +/- N hours? Why are there no subdirectories under /var/log/snort for IP addresses?Ì65536ÎConfiguring SnortÖ0 macro: Configuring Snort :: Why are there no subdirectories under /var/log/snort for IP addresses? Why can't snort see one of the 10Mbps or 100Mbps traffic on my autoswitch hub?Ì65536ÎProblemsÖ0 macro: Problems :: Why can't snort see one of the 10Mbps or 100Mbps traffic on my autoswitch hub? Why do certain alerts seem to have `unknown' IPs in BASE?Ì65536ÎRules and AlertsÖ0 macro: Rules and Alerts :: Why do certain alerts seem to have `unknown' IPs in BASE? Why do many Snort rules have the flags P (TCP PuSH) and A (TCP ACK) set?Ì65536ÎRules and AlertsÖ0 macro: Rules and Alerts :: Why do many Snort rules have the flags P (TCP PuSH) and A (TCP ACK) set? Why does Snort complain about /var/log/snort?Ì65536ÎGetting StartedÖ0 macro: Getting Started :: Why does Snort complain about /var/log/snort? Why does building Snort complain about missing references?Ì65536ÎGetting StartedÖ0 macro: Getting Started :: Why does building Snort complain about missing references? Why does building snort fail with errors about yylex and lex\_init?Ì65536ÎGetting StartedÖ0 macro: Getting Started :: Why does building snort fail with errors about yylex and lex\_init? Why does chrooted Snort die when I send it a SIGHUP? \label{chroot}Ì65536ÎProblemsÖ0 macro: Problems :: Why does chrooted Snort die when I send it a SIGHUP? \label{chroot} Why does snort report ``Packet loss statistics are unavailable under Linux?''Ì65536ÎProblemsÖ0 macro: Problems :: Why does snort report ``Packet loss statistics are unavailable under Linux?'' Why does the `error deleting alert' message occur when attempting to delete an alert with BASE?Ì65536ÎProblemsÖ0 macro: Problems :: Why does the `error deleting alert' message occur when attempting to delete an alert with BASE? Why does the portscan plugin log ``stealth'' packets even though the host is in the portscan-ignorehosts list?Ì65536ÎConfiguring SnortÖ0 macro: Configuring Snort :: Why does the portscan plugin log ``stealth'' packets even though the host is in the portscan-ignorehosts list? Why does the program generate alerts on packets that have pass rules?Ì65536ÎRules and AlertsÖ0 macro: Rules and Alerts :: Why does the program generate alerts on packets that have pass rules? \myquoteÌ16Ö0 function: \myquote \myrefÌ16Ö0 function: \myref centerÌ1Ö0 class: center documentÌ1Ö0 class: document enumerateÌ1Ö0 class: enumerate itemizeÌ1Ö0 class: itemize latexonlyÌ1Ö0 class: latexonly stealthÌ2048Ö0 struct: stealth stream4Ì2048Ö0 struct: stream4 tabularÌ1Ö0 class: tabular verbatimÌ1Ö0 class: verbatim geany-2.0/tests/ctags/simple.html.tags0000644000175000017500000000035014514252267014764 00000000000000messageÌ16Í()Ö0 function: message() postfixed_anchorÌ64Ö0 member: postfixed_anchor prefixed_anchorÌ64Ö0 member: prefixed_anchor simple_anchorÌ64Ö0 member: simple_anchor unquoted_anchorÌ64Ö0 member: unquoted_anchor geany-2.0/tests/ctags/stdcall.f.tags0000644000175000017500000000112314514252267014401 00000000000000D02CJWÌ16384Ö0 variable: D02CJW FCNÌ128Í(T, Y, F)Ö0 method: FCN(T, Y, F) GÌ16Ö0 function: G GÌ16384Ö0 variable: G HÌ16384Ö0 variable: H IÌ16384Ö0 variable: I IFAILÌ16384Ö0 variable: IFAIL IWÌ16384Ö0 variable: IW JÌ16384Ö0 variable: J KÌ16384Ö0 variable: K NÌ16384Ö0 variable: N NOUTÌ16384Ö0 variable: NOUT OUTÌ128Í(X, Y)Ö0 method: OUT(X, Y) PIÌ16384Ö0 variable: PI RELABSÌ16384Ö0 variable: RELABS TOLÌ16384Ö0 variable: TOL WÌ16384Ö0 variable: W XÌ16384Ö0 variable: X X01AAFÌ16384Ö0 variable: X01AAF XENDÌ16384Ö0 variable: XEND YÌ16384Ö0 variable: Y geany-2.0/tests/ctags/array-spec.f90.tags0000644000175000017500000000047114514252267015177 00000000000000df_mb_dataÌ64Îdf_typeÖ0 member: df_type :: df_mb_data df_mb_timeÌ64Îdf_typeÖ0 member: df_type :: df_mb_time df_typeÌ1Îinm_dfÖ0 class: inm_df :: df_type df_wb_dataÌ64Îdf_typeÖ0 member: df_type :: df_wb_data df_wb_timeÌ64Îdf_typeÖ0 member: df_type :: df_wb_time inm_dfÌ256Ö0 namespace: inm_df geany-2.0/tests/ctags/py-skipped-string.py0000644000175000017500000000117514514252267015621 00000000000000# triple start string immediately after a normal string not detected def f1(): ''""" The string above was not detected as triple start string, but the one below instead. """ print "f1" def f2(): ''""" The string above was then detected as end string, and the one below as start string again. """ print "f2" def f3(): """ The string below is prepared so that ctags with the bug does not start a new triple string. For a clean precondition for the next test. ''""" print "f3" # normal string immediately after a normal string not detected ''" import os\ " ""' def fX():\ ' geany-2.0/tests/ctags/js-sub-block-scope.js.tags0000644000175000017500000000054614514252267016554 00000000000000barÌ16Í()ÎparentÖ0 function: parent :: bar() fooÌ16Í()ÎparentÖ0 function: parent :: foo() helloÌ16Í()Îparent.fooÖ0 function: parent.foo :: hello() hello2Ì16Í()Îparent.barÖ0 function: parent.bar :: hello2() hiÌ16Í()Îparent.fooÖ0 function: parent.foo :: hi() hi2Ì16Í()Îparent.barÖ0 function: parent.bar :: hi2() parentÌ16Í()Ö0 function: parent() geany-2.0/tests/ctags/bug1770479.cpp0000644000175000017500000000026014514252267013714 00000000000000#include int main (int argc, char **argv) { std::ostringstream a; a << "a"; std::ostringstream b; b << "b"; return 0; } int foo (int i) { return i; } geany-2.0/tests/ctags/ada-task.adb.tags0000644000175000017500000000045714514252267014752 00000000000000Show_Simple_TasksÌ16Ö0 function: Show_Simple_Tasks TÌ128ÎShow_Simple_TasksÖ0 method: Show_Simple_Tasks :: T TÌ1024ÎShow_Simple_TasksÖ0 prototype: Show_Simple_Tasks :: T T2Ì128ÎShow_Simple_TasksÖ0 method: Show_Simple_Tasks :: T2 T2Ì1024ÎShow_Simple_TasksÖ0 prototype: Show_Simple_Tasks :: T2 geany-2.0/tests/ctags/simple.abc0000644000175000017500000000346014514252267013615 00000000000000% A Selection of Scotch, English, Irish and Foreign % Airs adapted to the Fife, Violin, or German-Flute % Glasgow % Printed and Sold by James Aird % Volume First % 1778 (often cited as 1782) X:0001 T:The Ranting Highlandman. T:The White Cockade M:C| L:1/8 Q:1/2=112 I: :: :: %% G A B c d e ^f g a Z:Jack Campin * www.campin.me.uk * 2009 K:G AG|B2B2 B2AG|B2B2 B2g2|B2B2 B2AG|AGAB A2 GA|B2B2 cBAG|A2B2 g2fg|a2gf g2fe|d2B2 B2:: Bc|d2B2 g2B2|d2d2 d2e2|d2cB g2fg|a2A2 A2 GA|B2B2 cBAG|A2B2 g2fg|a2gf g2fe|d2B2 B2:| X:0002 T:Quick Step. 25th Regt. N:bars of quavers are all beamed together in the original M:2/4 L:1/16 Q:1/4=89 I: :: :: %% D ^F G A B c d e f ^f g a Z:Jack Campin * www.campin.me.uk * 2009 K:G g2d2 d2c2|(BcdB) G2D2 |G2B2 (ABcd)| B2``G2 G2d2| e2c2 c2e2| d2B2 B2d2 |g2d2 c2B2 | B4 A4 :| F2A2 A2dc| B2G2 G4 |B2d2 d2=f2|(ed)(cB) c4 | e2a2 a2g2|(gfed) g2c2 |B2AG A2D2 | G2``G2 G4 :| X:0003 T:The Lads of the Village. M:2/4 L:1/8 Q:1/4=104 I: :: :: %% D ^F G A B c d e ^f g a Z:Jack Campin * www.campin.me.uk * 2009 K:G G2g>d|ecBG|a>cBG|FA`FD|G2 gd|ecBG|A>cBG|(D/G/``F/A/) G2:| g>fgd|ecBG|g>fge|a>gfd|g>fgd|ecBG|A>cBG|(D/G/)(F/A/) G2:| X:0004 T:I'll Touzle your Kurchy. M:6/8 L:1/8 Q:3/8=120 I: :: :: %% D E ^F G A B c d e ^f g Z:Jack Campin * www.campin.me.uk * 2009 K:E Minor B |E>GE GEG|B>AB e2f|g>fe dgB|A>GA BG E |E>GE GEG|B>AB e2f|g>fe dcB|AGF E2:| B |E>GE B2B|GEG B2B|E>GE A2G|FDF A2 G/F/|E>GE B2B|GEG e2f|gfe dcB|AGF E2:| X:0005 T:The Lady's play thing, or Gen Howe's March. M:6/8 L:1/8 Q:3/8=120 I: :: :: %% D G A B c d e g N:last note printed as G3 Z:Jack Campin * www.campin.me.uk * 2009 K:G d/c/|B2B Bcd|A2A A2d|G2G GAB|B3 A2 e |dgd BdB|GBG Ddc|BcB AGA|G2G G2:| d |dBd dBd|e2e e2c|cAc cAc|d2d d2 c |BGB BGB|c2c cBA|Bcd dcB|B3 A2 e |dgd BdB|GBG Ddc|BcB AGA|G2G G2:| geany-2.0/tests/ctags/python-comments.py0000644000175000017500000000021014514252267015361 00000000000000 import foo ## as bug1 "hello" ## import bug2 "hi" # something # class bug3 for i in range(1, 2): ##class bug4 pass ## class bug5 geany-2.0/tests/ctags/objectivec_implementation.mm0000644000175000017500000000565614514252267017443 00000000000000 @implementation FileTree - (FileSize)getDiskSize { return diskSize; } - (id)initWithName:(NSString*)treeName atPlace:(FolderTree*)parentFolder { self = [super init]; diskSize = 0; name = treeName; parent = parentFolder; [name retain]; representation = nil; return self; } - (id)initWithName:(NSString*)treeName andSize:(FileSize)size atPlace:(FolderTree*)parentFolder { self = [super init]; diskSize = size; name = treeName; parent = parentFolder; [name retain]; representation = nil; return self; } - (void)dealloc { [name release]; [representation release]; [super dealloc]; } - (LayoutTree*)createLayoutTree { return nil; } @end @implementation FolderTree - (id)initWithName:(NSString*)treeName atPlace:(FolderTree*)parentFolder { self = [super initWithName:treeName atPlace:parentFolder]; children = [[NSMutableArray alloc] init]; return self; } - (void)dealloc { [children release]; [super dealloc]; } + (void) createFileList: (NSString*)root atPlace:(FolderTree*)parentFolder { NSFileManager *localFileManager = [[NSFileManager alloc] init]; NSURL *rootUrl = [NSURL fileURLWithPath:root]; NSDirectoryEnumerator *dirEnumerator = [localFileManager enumeratorAtURL:rootUrl includingPropertiesForKeys:[NSArray arrayWithObjects: NSURLNameKey, NSURLIsDirectoryKey, nil] options:NSDirectoryEnumerationSkipsHiddenFiles errorHandler:nil]; for (NSURL *theURL in dirEnumerator) { [theURL getResourceValue:&fileName forKey:NSURLNameKey error:NULL]; // Ignore files under the _extras directory if ([isDirectory boolValue]==YES) { [folder populateChildList:root]; } else if ([isDirectory boolValue]==NO) { [parentFolder addChild:f]; } } } - (void) populateChildList:(NSString*)root { NSString *thisRoot = [[root stringByAppendingString:@"/"] stringByAppendingString:name]; [FolderTree createFileList:thisRoot atPlace:self]; for ( FileTree *f in children ) diskSize += [f getDiskSize]; } - (FolderTree*)addChild:(FileTree*)subTree { [children addObject:subTree]; return self; } - (LayoutTree*)createLayoutTree { return [[LayoutTree alloc] initWithFileList:children andTotalSize:diskSize]; } @end geany-2.0/tests/ctags/bug722501.sql.tags0000644000175000017500000000003214514252267014561 00000000000000fooÌ256Ö0 namespace: foo geany-2.0/tests/ctags/bug849591.cpp0000644000175000017500000000305114514252267013636 00000000000000/* Bugs item #849591, was opened at 2003-11-26 11:35 Message generated for change (Tracker Item Submitted) made by Item Submitter You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=106556&aid=849591&group_id=6556 Category: None Group: None Status: Open Resolution: None Priority: 5 Submitted By: Igor Proskuriakov (proskig) Assigned to: Nobody/Anonymous (nobody) Summary: C++ Member templates Initial Comment: Hi, There seems to be a problem with how ctags treats C++ member templates. Example: */ void MainClass< ParamClass1&, ParamClass2>::Foo() { exit(0); }; /* Generates erroneous tag ParamClass1 test.cpp /^void MainClass< ParamClass1&, ParamClass2>::Foo()$/;" v Full ctags file: !_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/ !_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/ !_TAG_PROGRAM_AUTHOR Darren Hiebert /dhiebert@users.sourceforge.net/ !_TAG_PROGRAM_NAME Exuberant Ctags // !_TAG_PROGRAM_URL http://ctags.sourceforge.net /official site/ !_TAG_PROGRAM_VERSION 5.5.2 // Foo test.cpp /^void MainClass< const ParamClass1&, ParamClass2>::Foo()$/;" f class:ParamClass2 ParamClass1 test.cpp /^void MainClass< ParamClass1&, ParamClass2>::Foo()$/;" v ----- Removing space after first angle bracket: */ void MainClass::Foo() { exit(0); }; /* makes ctags to drop first letter from parameter class name: aramClass1 test.cpp /^void MainClass::Foo()$/;" v Let me know if you need any clarification with this issue. Many thanks in advance! */ geany-2.0/tests/ctags/qualified_types.f90.tags0000644000175000017500000000065314514252267016322 00000000000000c1Ì64ÎgoodtypeÖ0 member: goodtype :: c1 c2Ì64ÎgoodtypeÖ0 member: goodtype :: c2 c3Ì64ÎgoodtypeÖ0 member: goodtype :: c3 c4Ì64ÎgoodtypeÖ0 member: goodtype :: c4 goodtypeÌ1ÎtestÖ0 class: test :: goodtype p1Ì64ÎgoodtypeÖ0 member: goodtype :: p1 p2Ì64ÎgoodtypeÖ0 member: goodtype :: p2 p3Ì64ÎgoodtypeÖ0 member: goodtype :: p3 p4Ì64ÎgoodtypeÖ0 member: goodtype :: p4 testÌ256Ö0 namespace: test geany-2.0/tests/ctags/vhdl-component.vhd.tags0000644000175000017500000000077614514252267016261 00000000000000ENTITY_1Ì64ÎENTITY_TOP.archÖ0 member: ENTITY_TOP.arch :: ENTITY_1 ENTITY_2Ì64ÎENTITY_TOP.archÖ0 member: ENTITY_TOP.arch :: ENTITY_2 ENTITY_TOPÌ1Ö0 class: ENTITY_TOP INPÌ16384ÎENTITY_TOPÖ0 variable: ENTITY_TOP :: INP INPÌ16384ÎENTITY_TOP.arch.ENTITY_1Ö0 variable: ENTITY_TOP.arch.ENTITY_1 :: INP INPÌ16384ÎENTITY_TOP.arch.ENTITY_2Ö0 variable: ENTITY_TOP.arch.ENTITY_2 :: INP archÌ2048ÎENTITY_TOPÖ0 struct: ENTITY_TOP :: arch sigÌ16384ÎENTITY_TOP.archÖ0 variable: ENTITY_TOP.arch :: sig geany-2.0/tests/ctags/bug665086.cpp0000644000175000017500000000120414514252267013627 00000000000000/* Bugs item #665086, was opened at 2003-01-09 15:30 You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=106556&aid=665086&group_id=6556 Category: None Group: None Status: Open Resolution: None Priority: 5 Submitted By: Welti Marco (cider101) Assigned to: Nobody/Anonymous (nobody) Summary: nested namespaces Initial Comment: hi it seems that ctags has ommits the scope for nested namespaces. */ namespace N1 { namespace N2 { class C12{} } } /* N1 test.h /^namespace N1$/;" namespace line:1 N2 test.h /^namespace N2$/;" namespace line:3 C12 test.h /^ class C12{};$/;" class line:5 namespace:N1::N2 */ geany-2.0/tests/ctags/bug1515910.cs0000644000175000017500000000044414514252267013526 00000000000000// Simple generic classes. public class MyGenericClass1 { } // Derived enums. enum Enum1 : byte { Value1, Values } // Verbatim strings. public class C { private string str1 = @"abc\"; private int int1 = 123; private string str2 = @"abc\"; private string str3 = "abc"; } geany-2.0/tests/ctags/objectivec_property.mm0000644000175000017500000000032514514252267016266 00000000000000 @interface Person : NSObject { @public NSString *m_name; @private int m_age; } @property(copy) NSString *personName; @property(readonly) int personAge; -(id)initWithAge:(int)age; @end geany-2.0/tests/ctags/css-tag-types.css.tags0000644000175000017500000000264014514252267016026 00000000000000#a #fooÌ16384Ö0 variable: #a #foo #a #foo #barÌ16384Ö0 variable: #a #foo #bar #a #foo .barÌ1Ö0 class: #a #foo .bar #a #foo barÌ2048Ö0 struct: #a #foo bar #a .fooÌ1Ö0 class: #a .foo #a .foo #barÌ16384Ö0 variable: #a .foo #bar #a .foo .barÌ1Ö0 class: #a .foo .bar #a .foo barÌ2048Ö0 struct: #a .foo bar #a fooÌ2048Ö0 struct: #a foo #a foo #barÌ16384Ö0 variable: #a foo #bar #a foo .barÌ1Ö0 class: #a foo .bar #a foo barÌ2048Ö0 struct: #a foo bar .a #fooÌ16384Ö0 variable: .a #foo .a #foo #barÌ16384Ö0 variable: .a #foo #bar .a #foo .barÌ1Ö0 class: .a #foo .bar .a #foo barÌ2048Ö0 struct: .a #foo bar .a .fooÌ1Ö0 class: .a .foo .a .foo #barÌ16384Ö0 variable: .a .foo #bar .a .foo .barÌ1Ö0 class: .a .foo .bar .a .foo barÌ2048Ö0 struct: .a .foo bar .a fooÌ2048Ö0 struct: .a foo .a foo #barÌ16384Ö0 variable: .a foo #bar .a foo .barÌ1Ö0 class: .a foo .bar .a foo barÌ2048Ö0 struct: .a foo bar a #fooÌ16384Ö0 variable: a #foo a #foo #barÌ16384Ö0 variable: a #foo #bar a #foo .barÌ1Ö0 class: a #foo .bar a #foo barÌ2048Ö0 struct: a #foo bar a .fooÌ1Ö0 class: a .foo a .foo #barÌ16384Ö0 variable: a .foo #bar a .foo .barÌ1Ö0 class: a .foo .bar a .foo barÌ2048Ö0 struct: a .foo bar a fooÌ2048Ö0 struct: a foo a foo #barÌ16384Ö0 variable: a foo #bar a foo .barÌ1Ö0 class: a foo .bar a foo barÌ2048Ö0 struct: a foo bar geany-2.0/tests/ctags/simple.hx.tags0000644000175000017500000000042414514252267014441 00000000000000ColorÌ2Ö0 enum: Color MainÌ1Ö0 class: Main PrintableÌ32Ö0 interface: Printable UserÌ4096Ö0 typedef: User ageÌ16384Ö0 variable: age mainÌ128Ö0 method: main memberÌ16384Ö0 variable: member nameÌ16384Ö0 variable: name toStringÌ128Ö0 method: toString geany-2.0/tests/ctags/bug1447756.java.tags0000644000175000017500000000012514514252267015007 00000000000000FooÌ32Ö0 interface: Foo barÌ128Í()ÎFooÖ0Ïpublic T method: public T Foo :: bar() geany-2.0/tests/ctags/case_sensitivity.php.tags0000644000175000017500000000057014514252267016707 00000000000000AÌ1Ö0 class: A BÌ1Ö0 class: B CÌ1Ö0 class: C DÌ1Ö0 class: D aÌ16Í()Ö0 function: a() bÌ16Í()Ö0 function: b() cÌ16Í()Ö0 function: c() dÌ16Í()Ö0 function: d() iAÌ32Ö0 interface: iA iBÌ32Ö0 interface: iB iCÌ32Ö0 interface: iC iDÌ32Ö0 interface: iD tAÌ2048Ö0 struct: tA tBÌ2048Ö0 struct: tB tCÌ2048Ö0 struct: tC tDÌ2048Ö0 struct: tD geany-2.0/tests/ctags/bug1856363.py0000644000175000017500000000025314514252267013561 00000000000000#!/usr/bin/python def main(): # A broken ctags will see a function "initely_not_a_function" here. definitely_not_a_function = 0 return if __name__ == 'main': main() geany-2.0/tests/ctags/bug1988130.py0000644000175000017500000000024114514252267013554 00000000000000def testFunc(): print 'The following works now' + '"""' def main(): print 'nothing' print 'This is another quoted triple string: """.' return 0 geany-2.0/tests/ctags/jsFunc_tutorial.js0000644000175000017500000002564314514252267015375 00000000000000 /* * These samples were retrieved from this website: * http://www.permadi.com/tutorial/jsFunc/ * * This the output you should see from running: * ctags -f - Test/jsFunc_tutorial.js * functions * Ball1 * Ball3 * D1 * D2 * D2A * D3 * D4 * D5 * DT1 * DT2 * DT2A * DT3 * PT1 * calculate8 * getHalfOf7 * getHalfOf7.calculate * getHalfOf8 * getSalaryFunctionDT9 * myFunction4 * myFunction5 * myFunction6 * myFunction6A * myFunction6AE * myFunction6B * myFunction6E * myObject.add * savedFunc6B * sayName4A * theAdd * classes * DT4 * DT5 * DT6 * DT7 * DT7A * DT8 * DT9 * PT2 * PT3 * addSalaryFunction * addSalaryFunctionDT9 * methods * DT7.getSalary * DT7A.getSalary * DT8.getSalary * PT2.livesIn * PT2.price * PT3.addSalary * PT3.getSalary * variables * my_global_var1 */ // Example D1 function D1(a, b) { return a+b; } alert(D1(1,2)); // produces 3 var my_global_var1 = 'global'; // Example D2 var D2=function(a, b) { return a+b; } alert(D2(1,2)); // produces 3 // Example D2A var D2A=function theAdd(a, b) { return a+b; } alert(D2A(1,2)); // produces 3 alert(theAdd(1,2)); // also produces 3 var myObject=new Object(); myObject.add=function(a,b){return a+b}; // myObject now has a property/a method named "add" // and I can use it like below myObject.add(1, 2); // Example D3 var D3=new Function("a", "b", "return a+b;"); alert(D3(3,4)); // produces 7 // Example D4 var D4=new Function("a", "b", // separate string using "\" "('adding '+a+' and ' +b);\ return a+b;"); alert(D4(3,4)); // produces 7 // Example D5 function D5(myOperator) { return new Function("a", "b", "return a" + myOperator + "b;"); } var add=D5("+"); // creates "add" function var subtract=D5("-"); // creates "subtract" function var multiply=D5("*"); // created "multiply" function // test the functions alert("result of add="+add(10,2)); // result is 12 alert("result of subtract="+subtract(10,2)); // result is 8 alert("result of multiply="+multiply(10,2)); // result is 20 alert(add); // Example 1 function Ball1() // it may seem odd, but this declaration { // creates a object named Ball i=1; } alert(typeof Ball1); // produces "function" // Example 3 function Ball3() // it may seem odd, but declaration { // creates an object named Ball, and you can } // refer to it or add properties to it like below Ball3.callsign="The Ball"; // add property to Ball alert(Ball3.callsign); // produces "The Ball" // Example 4 function myFunction4(message) { alert(message); } var ptr=myFunction4; // ptr points to myFunction ptr("hello"); // executes myFunction which will prints "hello" // Example 4A function sayName4A(name) { alert(name); } var object1=new Object(); // creates 3 objects var object2=new Object(); var object3=new Object(); object1.sayMyName4A=sayName; // assign the function to all objects object2.sayMyName4A=sayName; object3.sayMyName4A=sayName; object1.sayMyName4A("object1"); // prints "object1" object2.sayMyName4A("object2"); // prints "object2" object3.sayMyName4A("object3"); // prints "object3" // Example 5 function myFunction5() { alert(myFunction.message); } myFunction5.message="old"; var ptr1=myFunction5; // ptr1 points to myFunction var ptr2=myFunction5; // ptr2 also points to myFunction ptr1(); // prints "old" ptr2(); // prints "old" myFunction5.message="new"; ptr1(); // prints "new" ptr2(); // prints "new" //Example 6: function myFunction6() { alert("Old"); } myFunction6(); // prints "Old" myFunction6E=function() { alert("New"); }; myFunction6E(); // prints "New" //Example 6A: function myFunction6A() { alert("Old"); } var savedFunction=myFunction6A; myFunction6AE=function() { alert("New"); }; myFunction6AE(); // prints "New" savedFunction(); // printf "Old" //Example 6B: function myFunction6B() { alert("Old"); } var savedFunc=myFunction6B; savedFunc6B=function() { alert("New"); }; myFunction6B(); // prints "Old" savedFunc6B(); // prints "New" // Example 7 function getHalfOf7(num1, num2, num3) { function calculate(number) { return number/2; } var result=""; result+=calculate(num1)+" "; result+=calculate(num2)+" "; result+=calculate(num3); } var resultString=getHalfOf7(10,20,30); alert(resultString); // prints "5 10 15" // Example 8 function calculate8(number) { return number/3; } function getHalfOf8(num1, num2, num3) { function calculate(number) { return number/2; } var result=""; result+=calculate(num1)+" "; result+=calculate(num2)+" "; result+=calculate(num3); } var resultString=getHalfOf8(10,20,30); alert(resultString); // prints "5 10 15" // Example DT1 function DT1() { } var ball0=new DT1(); // ball0 now points to a new object alert(ball0); // prints "Object" because ball0 is now an Object // Example DT2 function DT2(message) { alert(message); } var ball1=new DT2("creating new Ball"); // creates object & // prints the message ball1.name="ball-1"; // ball0 now has a "name" property alert(ball1.name); // prints "ball-0" // Example DT2A function DT2A(message) { alert(message); } var ball2=new Object(); ball2.construct=DT2A; ball2.construct("creating new ball2"); // executes ball0.Ball("creating.."); ball2.name="ball-2"; alert(ball2.name); // Example DT3 (creates 3 ball objects) function DT3() { } var ball3=new DT3(); // ball0 now points to a new instance of type Ball ball3.name="ball-3"; // ball0 now has a "name" property var ball4=new DT3(); ball4.name="ball-4"; var ball5=new DT3(); alert(ball0.name); // prints "ball-0" alert(ball1.name); // prints "ball-1" alert(ball2.name); // oops, I forgot to add "name" to ball2! // Example DT4 function DT4(message, specifiedName) { alert(message); this.name=specifiedName; } var ball6=new DT4("creating new Ball", "Soccer Ball"); alert(ball6.name); // prints "Soccer Ball" // Example DT5 function DT5(color, specifiedName, owner, weight) { this.name=specifiedName; this.color=color; this.owner=owner; this.weight=weigth; } var ball7=new DT5("black/white", "Soccer Ball", "John", 20); var ball8=new DT5("gray", "Bowling Ball", "John", 30); var ball9=new DT5("yellow", "Golf Ball", "John", 55); var balloon=new DT5("red", "Balloon", "Pete", 10); alert(ball7.name); // prints "Soccer Ball" alert(balloon.name); // prints "Balloon" alert(ball9.weight); // prints "55" // Example DT6 function DT6(name, salary, mySupervisor) { this.name=name; this.salary=salary; this.supervisor=mySupervisor; } var boss=new DT6("John", 200); var manager=new DT6("Joan", 50, boss); var teamLeader=new DT6("Rose", 50, boss); alert(manager.supervisor.name+" is the supervisor of "+manager.name); alert(manager.name+"\'s supervisor is "+manager.supervisor.name); // Example DT7 function DT7(name, salary) { this.name=name; this.salary=salary; this.addSalary=addSalaryFunction; this.getSalary=function() { return this.salary; }; } function addSalaryFunction(addition) { this.salary=this.salary+addition; } var boss=new DT7("John", 200000); boss.addSalary(10000); // boss gets 10K raise alert(boss.getSalary()); // print 210K function DT7A(name, salary) { this.name=name; this.salary=salary; this.addSalary=addSalaryFunction; this.getSalary=function() { return this.salary; }; } function addSalaryFunction(addition) { this.salary=this.salary+addition; } var boss=new DT7A("John", 200000); var boss2=new DT7A("Joan", 200000); var boss3=new DT7A("Kim", 200000); // Example DT8 function DT8(name, salary) { this.name=name; this.salary=salary; this.addSalary=addSalaryFunction; this.getSalary=function() { return this.salary; }; } function addSalaryFunction(addition) { this.salary=this.salary+addition; } var boss1=new DT8("John", 200000); var boss2=new DT8("Joan", 200000); // add properties to getSalary function object. boss1.getSalary.owner="boss1"; boss2.getSalary.owner="boss2"; alert(boss1.getSalary.owner); // prints "boss1" alert(boss2.getSalary.owner); // prints "boss2" // if both objects are pointing to the same function object, then // both output above should have printed "boss2". // add properties to addSalary function object. boss1.addSalary.owner="boss1"; boss1.addSalary.owner="boss2"; alert(boss1.addSalary.owner); // prints "boss2" alert(boss2.addSalary.owner); // prints "boss2" // since both objects are not pointing to the same function, // then changes in one, affects all instances (so, both prints "boss2"). // Example DT9 function DT9(name, salary) { this.name=name; this.salary=salary; this.addSalary=addSalaryFunctionDT9; this.getSalary=getSalaryFunctionDT9; } function getSalaryFunctionDT9() { return this.salary; } function addSalaryFunctionDT9(addition) { this.salary=this.salary+addition; } // Example PT1 function PT1() { } alert(PT1.prototype); // prints "Object" // Example PT2 function PT2(name, color) { this.name=name; this.color=color; } PT2.prototype.livesIn="water"; PT2.prototype.price=20; // Example PT3 function PT3(name, salary) { this.name=name; this.salary=salary; } PT3.prototype.getSalary=function getSalaryFunction() { return this.salary; } PT3.prototype.addSalary=function addSalaryFunction(addition) { this.salary=this.salary+addition; } geany-2.0/INSTALL0000644000175000017500000003662614514252267010455 00000000000000Installation Instructions ************************* Copyright (C) 1994-1996, 1999-2002, 2004-2017, 2020-2021 Free Software Foundation, Inc. Copying and distribution of this file, with or without modification, are permitted in any medium without royalty provided the copyright notice and this notice are preserved. This file is offered as-is, without warranty of any kind. Basic Installation ================== Briefly, the shell command './configure && make && make install' should configure, build, and install this package. The following more-detailed instructions are generic; see the 'README' file for instructions specific to this package. Some packages provide this 'INSTALL' file but do not implement all of the features documented below. The lack of an optional feature in a given package is not necessarily a bug. More recommendations for GNU packages can be found in *note Makefile Conventions: (standards)Makefile Conventions. The 'configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses those values to create a 'Makefile' in each directory of the package. It may also create one or more '.h' files containing system-dependent definitions. Finally, it creates a shell script 'config.status' that you can run in the future to recreate the current configuration, and a file 'config.log' containing compiler output (useful mainly for debugging 'configure'). It can also use an optional file (typically called 'config.cache' and enabled with '--cache-file=config.cache' or simply '-C') that saves the results of its tests to speed up reconfiguring. Caching is disabled by default to prevent problems with accidental use of stale cache files. If you need to do unusual things to compile the package, please try to figure out how 'configure' could check whether to do them, and mail diffs or instructions to the address given in the 'README' so they can be considered for the next release. If you are using the cache, and at some point 'config.cache' contains results you don't want to keep, you may remove or edit it. The file 'configure.ac' (or 'configure.in') is used to create 'configure' by a program called 'autoconf'. You need 'configure.ac' if you want to change it or regenerate 'configure' using a newer version of 'autoconf'. The simplest way to compile this package is: 1. 'cd' to the directory containing the package's source code and type './configure' to configure the package for your system. Running 'configure' might take a while. While running, it prints some messages telling which features it is checking for. 2. Type 'make' to compile the package. 3. Optionally, type 'make check' to run any self-tests that come with the package, generally using the just-built uninstalled binaries. 4. Type 'make install' to install the programs and any data files and documentation. When installing into a prefix owned by root, it is recommended that the package be configured and built as a regular user, and only the 'make install' phase executed with root privileges. 5. Optionally, type 'make installcheck' to repeat any self-tests, but this time using the binaries in their final installed location. This target does not install anything. Running this target as a regular user, particularly if the prior 'make install' required root privileges, verifies that the installation completed correctly. 6. You can remove the program binaries and object files from the source code directory by typing 'make clean'. To also remove the files that 'configure' created (so you can compile the package for a different kind of computer), type 'make distclean'. There is also a 'make maintainer-clean' target, but that is intended mainly for the package's developers. If you use it, you may have to get all sorts of other programs in order to regenerate files that came with the distribution. 7. Often, you can also type 'make uninstall' to remove the installed files again. In practice, not all packages have tested that uninstallation works correctly, even though it is required by the GNU Coding Standards. 8. Some packages, particularly those that use Automake, provide 'make distcheck', which can by used by developers to test that all other targets like 'make install' and 'make uninstall' work correctly. This target is generally not run by end users. Compilers and Options ===================== Some systems require unusual options for compilation or linking that the 'configure' script does not know about. Run './configure --help' for details on some of the pertinent environment variables. You can give 'configure' initial values for configuration parameters by setting variables in the command line or in the environment. Here is an example: ./configure CC=c99 CFLAGS=-g LIBS=-lposix *Note Defining Variables::, for more details. Compiling For Multiple Architectures ==================================== You can compile the package for more than one kind of computer at the same time, by placing the object files for each architecture in their own directory. To do this, you can use GNU 'make'. 'cd' to the directory where you want the object files and executables to go and run the 'configure' script. 'configure' automatically checks for the source code in the directory that 'configure' is in and in '..'. This is known as a "VPATH" build. With a non-GNU 'make', it is safer to compile the package for one architecture at a time in the source code directory. After you have installed the package for one architecture, use 'make distclean' before reconfiguring for another architecture. On MacOS X 10.5 and later systems, you can create libraries and executables that work on multiple system types--known as "fat" or "universal" binaries--by specifying multiple '-arch' options to the compiler but only a single '-arch' option to the preprocessor. Like this: ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ CPP="gcc -E" CXXCPP="g++ -E" This is not guaranteed to produce working output in all cases, you may have to build one architecture at a time and combine the results using the 'lipo' tool if you have problems. Installation Names ================== By default, 'make install' installs the package's commands under '/usr/local/bin', include files under '/usr/local/include', etc. You can specify an installation prefix other than '/usr/local' by giving 'configure' the option '--prefix=PREFIX', where PREFIX must be an absolute file name. You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you pass the option '--exec-prefix=PREFIX' to 'configure', the package uses PREFIX as the prefix for installing programs and libraries. Documentation and other data files still use the regular prefix. In addition, if you use an unusual directory layout you can give options like '--bindir=DIR' to specify different values for particular kinds of files. Run 'configure --help' for a list of the directories you can set and what kinds of files go in them. In general, the default for these options is expressed in terms of '${prefix}', so that specifying just '--prefix' will affect all of the other directory specifications that were not explicitly provided. The most portable way to affect installation locations is to pass the correct locations to 'configure'; however, many packages provide one or both of the following shortcuts of passing variable assignments to the 'make install' command line to change installation locations without having to reconfigure or recompile. The first method involves providing an override variable for each affected directory. For example, 'make install prefix=/alternate/directory' will choose an alternate location for all directory configuration variables that were expressed in terms of '${prefix}'. Any directories that were specified during 'configure', but not in terms of '${prefix}', must each be overridden at install time for the entire installation to be relocated. The approach of makefile variable overrides for each directory variable is required by the GNU Coding Standards, and ideally causes no recompilation. However, some platforms have known limitations with the semantics of shared libraries that end up requiring recompilation when using this method, particularly noticeable in packages that use GNU Libtool. The second method involves providing the 'DESTDIR' variable. For example, 'make install DESTDIR=/alternate/directory' will prepend '/alternate/directory' before all installation names. The approach of 'DESTDIR' overrides is not required by the GNU Coding Standards, and does not work on platforms that have drive letters. On the other hand, it does better at avoiding recompilation issues, and works well even when some directory options were not specified in terms of '${prefix}' at 'configure' time. Optional Features ================= If the package supports it, you can cause programs to be installed with an extra prefix or suffix on their names by giving 'configure' the option '--program-prefix=PREFIX' or '--program-suffix=SUFFIX'. Some packages pay attention to '--enable-FEATURE' options to 'configure', where FEATURE indicates an optional part of the package. They may also pay attention to '--with-PACKAGE' options, where PACKAGE is something like 'gnu-as' or 'x' (for the X Window System). The 'README' should mention any '--enable-' and '--with-' options that the package recognizes. For packages that use the X Window System, 'configure' can usually find the X include and library files automatically, but if it doesn't, you can use the 'configure' options '--x-includes=DIR' and '--x-libraries=DIR' to specify their locations. Some packages offer the ability to configure how verbose the execution of 'make' will be. For these packages, running './configure --enable-silent-rules' sets the default to minimal output, which can be overridden with 'make V=1'; while running './configure --disable-silent-rules' sets the default to verbose, which can be overridden with 'make V=0'. Particular systems ================== On HP-UX, the default C compiler is not ANSI C compatible. If GNU CC is not installed, it is recommended to use the following options in order to use an ANSI C compiler: ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" and if that doesn't work, install pre-built binaries of GCC for HP-UX. HP-UX 'make' updates targets which have the same timestamps as their prerequisites, which makes it generally unusable when shipped generated files such as 'configure' are involved. Use GNU 'make' instead. On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot parse its '' header file. The option '-nodtk' can be used as a workaround. If GNU CC is not installed, it is therefore recommended to try ./configure CC="cc" and if that doesn't work, try ./configure CC="cc -nodtk" On Solaris, don't put '/usr/ucb' early in your 'PATH'. This directory contains several dysfunctional programs; working variants of these programs are available in '/usr/bin'. So, if you need '/usr/ucb' in your 'PATH', put it _after_ '/usr/bin'. On Haiku, software installed for all users goes in '/boot/common', not '/usr/local'. It is recommended to use the following options: ./configure --prefix=/boot/common Specifying the System Type ========================== There may be some features 'configure' cannot figure out automatically, but needs to determine by the type of machine the package will run on. Usually, assuming the package is built to be run on the _same_ architectures, 'configure' can figure that out, but if it prints a message saying it cannot guess the machine type, give it the '--build=TYPE' option. TYPE can either be a short name for the system type, such as 'sun4', or a canonical name which has the form: CPU-COMPANY-SYSTEM where SYSTEM can have one of these forms: OS KERNEL-OS See the file 'config.sub' for the possible values of each field. If 'config.sub' isn't included in this package, then this package doesn't need to know the machine type. If you are _building_ compiler tools for cross-compiling, you should use the option '--target=TYPE' to select the type of system they will produce code for. If you want to _use_ a cross compiler, that generates code for a platform different from the build platform, you should specify the "host" platform (i.e., that on which the generated programs will eventually be run) with '--host=TYPE'. Sharing Defaults ================ If you want to set default values for 'configure' scripts to share, you can create a site shell script called 'config.site' that gives default values for variables like 'CC', 'cache_file', and 'prefix'. 'configure' looks for 'PREFIX/share/config.site' if it exists, then 'PREFIX/etc/config.site' if it exists. Or, you can set the 'CONFIG_SITE' environment variable to the location of the site script. A warning: not all 'configure' scripts look for a site script. Defining Variables ================== Variables not defined in a site shell script can be set in the environment passed to 'configure'. However, some packages may run configure again during the build, and the customized values of these variables may be lost. In order to avoid this problem, you should set them in the 'configure' command line, using 'VAR=value'. For example: ./configure CC=/usr/local2/bin/gcc causes the specified 'gcc' to be used as the C compiler (unless it is overridden in the site shell script). Unfortunately, this technique does not work for 'CONFIG_SHELL' due to an Autoconf limitation. Until the limitation is lifted, you can use this workaround: CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash 'configure' Invocation ====================== 'configure' recognizes the following options to control how it operates. '--help' '-h' Print a summary of all of the options to 'configure', and exit. '--help=short' '--help=recursive' Print a summary of the options unique to this package's 'configure', and exit. The 'short' variant lists options used only in the top level, while the 'recursive' variant lists options also present in any nested packages. '--version' '-V' Print the version of Autoconf used to generate the 'configure' script, and exit. '--cache-file=FILE' Enable the cache: use and save the results of the tests in FILE, traditionally 'config.cache'. FILE defaults to '/dev/null' to disable caching. '--config-cache' '-C' Alias for '--cache-file=config.cache'. '--quiet' '--silent' '-q' Do not print messages saying which checks are being made. To suppress all normal output, redirect it to '/dev/null' (any error messages will still be shown). '--srcdir=DIR' Look for the package's source code in directory DIR. Usually 'configure' can determine that directory automatically. '--prefix=DIR' Use DIR as the installation prefix. *note Installation Names:: for more details, including other options available for fine-tuning the installation locations. '--no-create' '-n' Run the configure checks, but stop before creating any output files. 'configure' also accepts some other, not widely useful, options. Run 'configure --help' for more details. geany-2.0/Makefile.in0000644000175000017500000010440014514252334011446 00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = . ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx_17.m4 \ $(top_srcdir)/m4/geany-binreloc.m4 \ $(top_srcdir)/m4/geany-docutils.m4 \ $(top_srcdir)/m4/geany-doxygen.m4 \ $(top_srcdir)/m4/geany-gtk.m4 \ $(top_srcdir)/m4/geany-gtkdoc-header.m4 \ $(top_srcdir)/m4/geany-lib.m4 \ $(top_srcdir)/m4/geany-mac-integration.m4 \ $(top_srcdir)/m4/geany-mingw.m4 \ $(top_srcdir)/m4/geany-plugins.m4 \ $(top_srcdir)/m4/geany-prog-cxx.m4 \ $(top_srcdir)/m4/geany-revision.m4 \ $(top_srcdir)/m4/geany-socket.m4 \ $(top_srcdir)/m4/geany-status.m4 \ $(top_srcdir)/m4/geany-the-force.m4 \ $(top_srcdir)/m4/geany-utils.m4 $(top_srcdir)/m4/geany-vte.m4 \ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/iconv.m4 \ $(top_srcdir)/m4/intlmacosx.m4 $(top_srcdir)/m4/lib-ld.m4 \ $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \ $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ $(am__configure_deps) $(am__DIST_COMMON) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(install_sh) -d CONFIG_HEADER = config.h CONFIG_CLEAN_FILES = data/filedefs/filetypes.python geany.pc geany.nsi CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(desktopdir)" \ "$(DESTDIR)$(pkgconfigdir)" DATA = $(desktop_DATA) $(pkgconfig_DATA) RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ cscope distdir distdir-am dist dist-all distcheck am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) \ config.h.in # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` DIST_SUBDIRS = $(SUBDIRS) am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in \ $(srcdir)/geany.nsi.in $(srcdir)/geany.pc.in \ $(top_srcdir)/build-aux/ar-lib $(top_srcdir)/build-aux/compile \ $(top_srcdir)/build-aux/config.guess \ $(top_srcdir)/build-aux/config.rpath \ $(top_srcdir)/build-aux/config.sub \ $(top_srcdir)/build-aux/install-sh \ $(top_srcdir)/build-aux/ltmain.sh \ $(top_srcdir)/build-aux/missing \ $(top_srcdir)/data/filedefs/filetypes.python.in ABOUT-NLS \ AUTHORS COPYING ChangeLog INSTALL NEWS README THANKS TODO \ build-aux/ar-lib build-aux/compile build-aux/config.guess \ build-aux/config.rpath build-aux/config.sub \ build-aux/install-sh build-aux/ltmain.sh build-aux/missing DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) am__remove_distdir = \ if test -d "$(distdir)"; then \ find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ && rm -rf "$(distdir)" \ || { sleep 5 && rm -rf "$(distdir)"; }; \ else :; fi am__post_remove_distdir = $(am__remove_distdir) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best DIST_TARGETS = dist-gzip # Exists only to be overridden by the user if desired. AM_DISTCHECK_DVI_TARGET = dvi distuninstallcheck_listfiles = find . -type f -print am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' distcleancheck_listfiles = find . -type f -print pkgdatadir = @pkgdatadir@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DEPENDENCIES = @DEPENDENCIES@ DLLTOOL = @DLLTOOL@ DOXYGEN = @DOXYGEN@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GEANY_DATA_DIR = @GEANY_DATA_DIR@ GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ GMSGFMT = @GMSGFMT@ GMSGFMT_015 = @GMSGFMT_015@ GREP = @GREP@ GTK_CFLAGS = @GTK_CFLAGS@ GTK_LIBS = @GTK_LIBS@ GTK_VERSION = @GTK_VERSION@ HAVE_CXX17 = @HAVE_CXX17@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTLLIBS = @INTLLIBS@ INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBGEANY_CFLAGS = @LIBGEANY_CFLAGS@ LIBGEANY_EXPORT_CFLAGS = @LIBGEANY_EXPORT_CFLAGS@ LIBGEANY_LDFLAGS = @LIBGEANY_LDFLAGS@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBICONV = @LTLIBICONV@ LTLIBINTL = @LTLIBINTL@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAC_INTEGRATION_CFLAGS = @MAC_INTEGRATION_CFLAGS@ MAC_INTEGRATION_LIBS = @MAC_INTEGRATION_LIBS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POSUB = @POSUB@ PYTHON = @PYTHON@ PYTHON_COMMAND = @PYTHON_COMMAND@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RST2HTML = @RST2HTML@ RST2PDF = @RST2PDF@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SORT = @SORT@ STRIP = @STRIP@ UNIQ = @UNIQ@ USE_NLS = @USE_NLS@ VERSION = @VERSION@ XGETTEXT = @XGETTEXT@ XGETTEXT_015 = @XGETTEXT_015@ XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = ctags scintilla src plugins icons po doc data tests AUTOMAKE_OPTIONS = 1.7 ACLOCAL_AMFLAGS = -I m4 AM_DISTCHECK_CONFIGURE_FLAGS = --enable-api-docs --enable-html-docs --enable-pdf-docs \ --enable-gtkdoc-header WIN32_BUILD_FILES = \ geany_private.rc \ geany.exe.manifest EXTRA_DIST = \ autogen.sh \ scripts/gen-api-gtkdoc.py \ scripts/gen-signallist.sh \ scripts/print-tags.py \ geany.desktop.in \ geany.pc.in \ ChangeLog.pre-1-22 \ HACKING \ README.I18N \ README.Packagers \ $(WIN32_BUILD_FILES) DISTCLEANFILES = \ geany.desktop pkgconfig_DATA = geany.pc pkgconfigdir = $(libdir)/pkgconfig desktopdir = $(datadir)/applications desktop_in_files = geany.desktop.in desktop_DATA = $(desktop_in_files:.desktop.in=.desktop) all: config.h $(MAKE) $(AM_MAKEFLAGS) all-recursive .SUFFIXES: am--refresh: Makefile @: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ echo ' cd $(srcdir) && $(AUTOMAKE) --gnu'; \ $(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ echo ' $(SHELL) ./config.status'; \ $(SHELL) ./config.status;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck $(top_srcdir)/configure: $(am__configure_deps) $(am__cd) $(srcdir) && $(AUTOCONF) $(ACLOCAL_M4): $(am__aclocal_m4_deps) $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) $(am__aclocal_m4_deps): config.h: stamp-h1 @test -f $@ || rm -f stamp-h1 @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1 stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status @rm -f stamp-h1 cd $(top_builddir) && $(SHELL) ./config.status config.h $(srcdir)/config.h.in: $(am__configure_deps) ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) rm -f stamp-h1 touch $@ distclean-hdr: -rm -f config.h stamp-h1 data/filedefs/filetypes.python: $(top_builddir)/config.status $(top_srcdir)/data/filedefs/filetypes.python.in cd $(top_builddir) && $(SHELL) ./config.status $@ geany.pc: $(top_builddir)/config.status $(srcdir)/geany.pc.in cd $(top_builddir) && $(SHELL) ./config.status $@ geany.nsi: $(top_builddir)/config.status $(srcdir)/geany.nsi.in cd $(top_builddir) && $(SHELL) ./config.status $@ mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs distclean-libtool: -rm -f libtool config.lt install-desktopDATA: $(desktop_DATA) @$(NORMAL_INSTALL) @list='$(desktop_DATA)'; test -n "$(desktopdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(desktopdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(desktopdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(desktopdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(desktopdir)" || exit $$?; \ done uninstall-desktopDATA: @$(NORMAL_UNINSTALL) @list='$(desktop_DATA)'; test -n "$(desktopdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(desktopdir)'; $(am__uninstall_files_from_dir) install-pkgconfigDATA: $(pkgconfig_DATA) @$(NORMAL_INSTALL) @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(pkgconfigdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \ done uninstall-pkgconfigDATA: @$(NORMAL_UNINSTALL) @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir) # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscope: cscope.files test ! -s cscope.files \ || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) clean-cscope: -rm -f cscope.files cscope.files: clean-cscope cscopelist cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -rm -f cscope.out cscope.in.out cscope.po.out cscope.files distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) $(am__remove_distdir) test -d "$(distdir)" || mkdir "$(distdir)" @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" distdir="$(distdir)" \ dist-hook -test -n "$(am__skip_mode_fix)" \ || find "$(distdir)" -type d ! -perm -755 \ -exec chmod u+rwx,go+rx {} \; -o \ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r "$(distdir)" dist-gzip: distdir tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz $(am__post_remove_distdir) dist-bzip2: distdir tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 $(am__post_remove_distdir) dist-lzip: distdir tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz $(am__post_remove_distdir) dist-xz: distdir tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz $(am__post_remove_distdir) dist-zstd: distdir tardir=$(distdir) && $(am__tar) | zstd -c $${ZSTD_CLEVEL-$${ZSTD_OPT--19}} >$(distdir).tar.zst $(am__post_remove_distdir) dist-tarZ: distdir @echo WARNING: "Support for distribution archives compressed with" \ "legacy program 'compress' is deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z $(am__post_remove_distdir) dist-shar: distdir @echo WARNING: "Support for shar distribution archives is" \ "deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz $(am__post_remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) $(am__post_remove_distdir) dist dist-all: $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' $(am__post_remove_distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another # tarfile. distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lz*) \ lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ *.tar.xz*) \ xz -dc $(distdir).tar.xz | $(am__untar) ;;\ *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ *.tar.zst*) \ zstd -dc $(distdir).tar.zst | $(am__untar) ;;\ esac chmod -R a-w $(distdir) chmod u+w $(distdir) mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst chmod a-w $(distdir) test -d $(distdir)/_build || exit 0; \ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && am__cwd=`pwd` \ && $(am__cd) $(distdir)/_build/sub \ && ../../configure \ $(AM_DISTCHECK_CONFIGURE_FLAGS) \ $(DISTCHECK_CONFIGURE_FLAGS) \ --srcdir=../.. --prefix="$$dc_install_base" \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) $(AM_DISTCHECK_DVI_TARGET) \ && $(MAKE) $(AM_MAKEFLAGS) check \ && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ && $(MAKE) $(AM_MAKEFLAGS) uninstall \ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ distuninstallcheck \ && chmod -R a-w "$$dc_install_base" \ && ({ \ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ } || { rm -rf "$$dc_destdir"; exit 1; }) \ && rm -rf "$$dc_destdir" \ && $(MAKE) $(AM_MAKEFLAGS) dist \ && rm -rf $(DIST_ARCHIVES) \ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ && cd "$$am__cwd" \ || exit 1 $(am__post_remove_distdir) @(echo "$(distdir) archives ready for distribution: "; \ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' distuninstallcheck: @test -n '$(distuninstallcheck_dir)' || { \ echo 'ERROR: trying to run $@ with an empty' \ '$$(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ $(am__cd) '$(distuninstallcheck_dir)' || { \ echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left after uninstall:" ; \ if test -n "$(DESTDIR)"; then \ echo " (check DESTDIR support)"; \ fi ; \ $(distuninstallcheck_listfiles) ; \ exit 1; } >&2 distcleancheck: distclean @if test '$(srcdir)' = . ; then \ echo "ERROR: distcleancheck can only run from a VPATH build" ; \ exit 1 ; \ fi @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left in build directory after distclean:" ; \ $(distcleancheck_listfiles) ; \ exit 1; } >&2 check-am: all-am check: check-recursive all-am: Makefile $(DATA) config.h installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(desktopdir)" "$(DESTDIR)$(pkgconfigdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -f Makefile distclean-am: clean-am distclean-generic distclean-hdr \ distclean-libtool distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-data-local install-desktopDATA \ install-pkgconfigDATA install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-desktopDATA uninstall-local \ uninstall-pkgconfigDATA .MAKE: $(am__recursive_targets) all install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ am--refresh check check-am clean clean-cscope clean-generic \ clean-libtool cscope cscopelist-am ctags ctags-am dist \ dist-all dist-bzip2 dist-gzip dist-hook dist-lzip dist-shar \ dist-tarZ dist-xz dist-zip dist-zstd distcheck distclean \ distclean-generic distclean-hdr distclean-libtool \ distclean-tags distcleancheck distdir distuninstallcheck dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-data-local \ install-desktopDATA install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-pkgconfigDATA install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs installdirs-am \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am uninstall-desktopDATA \ uninstall-local uninstall-pkgconfigDATA .PRECIOUS: Makefile uninstall-local: rm -rf $(DESTDIR)$(pkgdatadir); # manually install some files under another name install-data-local: $(mkinstalldirs) $(DESTDIR)$(pkgdatadir) $(INSTALL_DATA) $(srcdir)/COPYING $(DESTDIR)$(pkgdatadir)/GPL-2 @MINGW_TRUE@ $(INSTALL_DATA) $(srcdir)/AUTHORS $(DESTDIR)$(prefix)/Authors.txt @MINGW_TRUE@ $(INSTALL_DATA) $(srcdir)/ChangeLog $(DESTDIR)$(prefix)/Changelog.txt @MINGW_TRUE@ $(INSTALL_DATA) $(srcdir)/COPYING $(DESTDIR)$(prefix)/Copying.txt @MINGW_TRUE@ $(INSTALL_DATA) $(srcdir)/README $(DESTDIR)$(prefix)/Readme.txt @MINGW_TRUE@ $(INSTALL_DATA) $(srcdir)/NEWS $(DESTDIR)$(prefix)/News.txt @MINGW_TRUE@ $(INSTALL_DATA) $(srcdir)/THANKS $(DESTDIR)$(prefix)/Thanks.txt @MINGW_TRUE@ $(INSTALL_DATA) $(srcdir)/TODO $(DESTDIR)$(prefix)/Todo.txt dist-hook: @if test -d "$(top_srcdir)/.git"; then \ echo ' GEN ChangeLog'; \ ( cd "$(top_srcdir)" && \ echo '# Generated by Makefile. Do not edit.' && echo && \ GIT_CONFIG_NOSYSTEM=1 HOME="$(srcdir)" XDG_CONFIG_HOME="$(srcdir)" \ git log --stat 0.21.0.. ) > ChangeLog.tmp \ && mv -f ChangeLog.tmp "$(distdir)/ChangeLog" \ || ( rm -f ChangeLog.tmp ; \ echo 'Failed to generate ChangeLog' >&2 ); \ else \ echo 'A git clone is required to generate a ChangeLog' >&2; \ fi sign: if test -f $(PACKAGE)-$(VERSION).tar.gz; then \ gpg --detach-sign --digest-algo SHA512 $(PACKAGE)-$(VERSION).tar.gz; fi if test -f $(PACKAGE)-$(VERSION).tar.bz2; then \ gpg --detach-sign --digest-algo SHA512 $(PACKAGE)-$(VERSION).tar.bz2; fi rpm: dist rpmbuild -ta $(distdir).tar.gz $(desktop_DATA): $(desktop_in_files) $(wildcard $(top_srcdir)/po/*.po) $(AM_V_GEN)$(MSGFMT) --desktop --template $< -d $(top_srcdir)/po -o $@ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: geany-2.0/scripts/0000755000175000017500000000000014514253232011147 500000000000000geany-2.0/scripts/gen-api-gtkdoc.py0000754000175000017500000004032414514252267014246 00000000000000#!/usr/bin/env python3 # # Copyright 2015 The Geany contributors # # This program 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; either version 2 of the License, or # (at your option) any later version. # # This program 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, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, # MA 02110-1301, USA. import os import sys import re from lxml import etree from optparse import OptionParser def normalize_text(s): r""" Normalizes whitespace in text. >>> normalize_text("asd xxx") 'asd xxx' >>> normalize_text(" asd\nxxx ") 'asd xxx' """ return s.replace("\n", " ").strip() CXX_NAMESPACE_RE = re.compile(r'[_a-zA-Z][_0-9a-zA-Z]*::') def fix_definition(s): """ Removes C++ name qualifications from some definitions. For example: >>> fix_definition("bool flag") 'bool flag' >>> fix_definition("bool FooBar::flag") 'bool flag' >>> fix_definition("void(* _GeanyObjectClass::project_open) (GKeyFile *keyfile)") 'void(* project_open) (GKeyFile *keyfile)' """ return CXX_NAMESPACE_RE.sub(r"", s) class AtDoc(object): def __init__(self): self.retval = None self.since = "" self.annot = [] def cb(self, type, str): if (type == "param"): words = str.split(" ", 2) self.annot = [] elif (type == "return"): self.annot = [] elif (type == "since"): self.since = str.rstrip() elif type in ("geany:nullable", "geany:optional", "geany:out", "geany:skip", "geany:closure", "geany:destroy"): self.annot.append(type.split(":")[1]) elif type in ("geany:array", "geany:transfer", "geany:element-type", "geany:scope"): type = type.split(":")[1] if len(str): str = " " + str self.annot.append("%s%s" % (type, str)) elif (type == "see"): return "See " + str elif type in ("a", "c") and str in ("NULL", "TRUE", "FALSE"): # FIXME: some of Geany does @a NULL instead of @c NULL return "%" + str elif (type == "a"): return "@" + str else: return str return "" class DoxygenProcess(object): def __init__(self): self.at = None # https://stackoverflow.com/questions/4624062/get-all-text-inside-a-tag-in-lxml @staticmethod def stringify_children(node): from lxml.etree import tostring from itertools import chain parts = ([node.text] + list(chain(*([c.text, tostring(c, encoding='unicode'), c.tail] for c in node.getchildren()))) + [node.tail]) # filter removes possible Nones in texts and tails return "".join(filter(None, parts)) def get_program_listing(self, xml): from lxml.etree import tostring arr = ["", "|["] for l in xml.getchildren(): if (l.tag == "codeline"): # a codeline is of the form # GeanyDocument*doc=...; # tags must be replaced with spaces, then just use the text h = l.find("highlight") if h is not None: html = tostring(h, encoding='unicode') html = html.replace("", " ") arr.append(" " + tostring(etree.HTML(html), method="text", encoding='unicode')) arr.append("]|") return "\n".join(arr) def join_annot(self): s = " ".join(map(lambda x: "(%s)" % x, self.at.annot)) return s + ": " if s else "" def process_element(self, xml): self.at = AtDoc() s = self.__process_element(xml) return s def get_extra(self): return self.join_annot() def get_return(self): return self.at.retval def get_since(self): return self.at.since def __process_element(self, xml): s = "" if xml.text: s += xml.text for n in xml.getchildren(): if n.tag == "emphasis": s += self.at.cb("a", self.__process_element(n)) if n.tag == "computeroutput": s += self.at.cb("c", self.__process_element(n)) if n.tag == "itemizedlist": s += "\n" + self.__process_element(n) if n.tag == "listitem": s += " - " + self.__process_element(n) if n.tag == "para": s += self.__process_element(n) + "\n" if n.tag == "ref": s += n.text if n.text else "" if n.tag == "simplesect": ss = self.at.cb(n.get("kind"), self.__process_element(n)) s += ss + "\n" if ss else "" if n.tag == "programlisting": s += self.get_program_listing(n) if n.tag == "xrefsect": s += self.__process_element(n) if n.tag == "xreftitle": s += self.__process_element(n) + ": " if n.tag == "xrefdescription": s += self.__process_element(n) if n.tag == "ulink": s += self.__process_element(n) if n.tag == "linebreak": s += "\n" if n.tag == "ndash": s += "--" # workaround for doxygen bug #646002 if n.tag == "htmlonly": s += "" if n.tail: s += n.tail if n.tag.startswith("param"): pass # parameters are handled separately in DoxyFunction::from_memberdef() return s class DoxyMember(object): def __init__(self, name, brief, extra=""): self.name = name self.brief = brief self.extra = extra class DoxyElement(object): def __init__(self, name, definition, **kwargs): self.name = name self.definition = definition self.brief = kwargs.get('brief', "") self.detail = kwargs.get('detail', "") self.members = kwargs.get('members', []) self.since = kwargs.get('since', "") self.extra = kwargs.get('extra', "") self.retval = kwargs.get('retval', None) def is_documented(self): if (normalize_text(self.brief)) != "": return True return False def add_brief(self, xml): proc = DoxygenProcess() self.brief = proc.process_element(xml) self.extra += proc.get_extra() def add_detail(self, xml): proc = DoxygenProcess() self.detail = proc.process_element(xml) self.extra += proc.get_extra() self.since = proc.get_since() def add_member(self, xml): name = xml.find("name").text proc = DoxygenProcess() brief = proc.process_element(xml.find("briefdescription")) # optional doxygen command output appears within proc.process_element(xml.find("detaileddescription")) self.members.append(DoxyMember(name, normalize_text(brief), proc.get_extra())) def add_param(self, xml): name = xml.find("parameternamelist").find("parametername").text proc = DoxygenProcess() brief = proc.process_element(xml.find("parameterdescription")) self.members.append(DoxyMember(name, normalize_text(brief), proc.get_extra())) def add_return(self, xml): proc = DoxygenProcess() brief = proc.process_element(xml) self.retval = DoxyMember("ret", normalize_text(brief), proc.get_extra()) def to_gtkdoc(self): s = [] s.append("/**") s.append(" * %s: %s" % (self.name, self.extra)) for p in self.members: s.append(" * @%s: %s %s" % (p.name, p.extra, p.brief)) s.append(" *") s.append(" * %s" % self.brief.replace("\n", "\n * ")) s.append(" *") s.append(" * %s" % self.detail.replace("\n", "\n * ")) s.append(" *") if self.retval: s.append(" * Returns: %s %s" % (self.retval.extra, self.retval.brief)) if self.since: s.append(" *") s.append(" * Since: %s" % self.since) s.append(" */") s.append("") return "\n".join(s) class DoxyTypedef(DoxyElement): @staticmethod def from_memberdef(xml): name = xml.find("name").text d = normalize_text(xml.find("definition").text) d += ";" return DoxyTypedef(name, d) class DoxyEnum(DoxyElement): @staticmethod def from_memberdef(xml): name = xml.find("name").text d = "typedef enum {\n" for member in xml.findall("enumvalue"): v = member.find("initializer") d += "\t%s%s,\n" % (member.find("name").text, " "+v.text if v is not None else "") d += "} %s;\n" % name e = DoxyEnum(name, d) e.add_brief(xml.find("briefdescription")) for p in xml.findall("enumvalue"): e.add_member(p) return e class DoxyStruct(DoxyElement): @staticmethod def from_compounddef(xml, typedefs=[]): name = xml.find("compoundname").text d = "struct %s {\n" % name memberdefs = xml.xpath(".//sectiondef[@kind='public-attrib']/memberdef") for p in memberdefs: # workaround for struct members. g-ir-scanner can't properly map struct members # (beginning with struct GeanyFoo) to the typedef and assigns a generic type for them # thus we fix that up here and enforce usage of the typedef. These are written # out first, before any struct definition, for this reason # Exception: there are no typedefs for GeanyFooPrivate so skip those. Their exact # type isn't needed anyway s = fix_definition(p.find("definition").text).lstrip() proc = DoxygenProcess() brief = proc.process_element(p.find("briefdescription")) private = (normalize_text(brief) == "") words = s.split() if (words[0] == "struct"): if not (words[1].endswith("Private") or words[1].endswith("Private*")): s = " ".join(words[1:]) d += "\t/*< %s >*/\n\t%s;\n" % ("private" if private else "public", s) d += "};\n" e = DoxyStruct(name, d) e.add_brief(xml.find("briefdescription")) for p in memberdefs: e.add_member(p) return e class DoxyFunction(DoxyElement): @staticmethod def from_memberdef(xml): name = xml.find("name").text d = normalize_text(xml.find("definition").text) d += " " + xml.find("argsstring").text + ";" d = normalize_text(d) e = DoxyFunction(name, d) e.add_brief(xml.find("briefdescription")) e.add_detail(xml.find("detaileddescription")) for p in xml.xpath(".//detaileddescription/*/parameterlist[@kind='param']/parameteritem"): e.add_param(p) x = xml.xpath(".//detaileddescription/*/simplesect[@kind='return']") if (len(x) > 0): e.add_return(x[0]) return e def main(args): xml_dir = None outfile = None scioutfile = None parser = OptionParser(usage="usage: %prog [options] XML_DIR") parser.add_option("--xmldir", metavar="DIRECTORY", help="Path to Doxygen-generated XML files", action="store", dest="xml_dir") parser.add_option("-d", "--outdir", metavar="DIRECTORY", help="Path to Doxygen-generated XML files", action="store", dest="outdir", default=".") parser.add_option("-o", "--output", metavar="FILE", help="Write output to FILE", action="store", dest="outfile") parser.add_option("--sci-output", metavar="FILE", help="Write output to FILE (only sciwrappers)", action="store", dest="scioutfile") opts, args = parser.parse_args(args[1:]) xml_dir = args[0] if not (os.path.exists(xml_dir)): sys.stderr.write("invalid xml directory\n") return 1 transform = etree.XSLT(etree.parse(os.path.join(xml_dir, "combine.xslt"))) doc = etree.parse(os.path.join(xml_dir, "index.xml")) root = transform(doc) other = [] enums = [] typedefs = [] c_files = root.xpath(".//compounddef[@kind='file']/compoundname[substring(.,string-length(.)-1)='.c']/..") h_files = root.xpath(".//compounddef[@kind='file']/compoundname[substring(.,string-length(.)-1)='.h']/..") for f in h_files: if not (f.find("compoundname").text.endswith("private.h")): for n0 in f.xpath(".//*/memberdef[@kind='typedef' and @prot='public']"): if not (DoxygenProcess.stringify_children(n0.find("type")).startswith("enum")): e = DoxyTypedef.from_memberdef(n0) typedefs.append(e) for n0 in f.xpath(".//*/memberdef[@kind='enum' and @prot='public']"): e = DoxyEnum.from_memberdef(n0) enums.append(e) for n0 in root.xpath(".//compounddef[@kind='struct' and @prot='public']"): e = DoxyStruct.from_compounddef(n0) other.append(e) for f in c_files: for n0 in f.xpath(".//*/memberdef[@kind='function' and @prot='public']"): e = DoxyFunction.from_memberdef(n0) other.append(e) if (opts.outfile): try: outfile = open(opts.outfile, "w+") except OSError as err: sys.stderr.write("failed to open \"%s\" for writing (%s)\n" % (opts.outfile, err.strerror)) return 1 else: outfile = sys.stdout if (opts.scioutfile): try: scioutfile = open(opts.scioutfile, "w+") except OSError as err: sys.stderr.write("failed to open \"%s\" for writing (%s)\n" % (opts.scioutfile, err.strerror)) return 1 else: scioutfile = outfile try: outfile.write("/*\n * Automatically generated file - do not edit\n */\n\n") outfile.write("#include \"gtkcompat.h\"\n") outfile.write("#include \"Scintilla.h\"\n") outfile.write("#include \"ScintillaWidget.h\"\n") if (scioutfile != outfile): scioutfile.write("/*\n * Automatically generated file - do not edit\n */\n\n") scioutfile.write("#include \"gtkcompat.h\"\n") scioutfile.write("#include \"Scintilla.h\"\n") scioutfile.write("#include \"ScintillaWidget.h\"\n") # write enums first, so typedefs to them are valid (as forward enum declaration # is invalid). It's fine as an enum can't contain reference to other types. for e in filter(lambda x: x.is_documented(), enums): outfile.write("\n\n") outfile.write(e.to_gtkdoc()) outfile.write(e.definition) outfile.write("\n\n") # write typedefs second, they are possibly undocumented but still required (even # if they are documented, they must be written out without gtkdoc) for e in typedefs: outfile.write(e.definition) outfile.write("\n\n") # write the rest (structures, functions, ...) for e in filter(lambda x: x.is_documented(), other): outfile.write("\n\n") outfile.write(e.to_gtkdoc()) outfile.write(e.definition) outfile.write("\n\n") if (e.name.startswith("sci_")): if (scioutfile != outfile): scioutfile.write("\n\n") scioutfile.write(e.to_gtkdoc()) scioutfile.write(e.definition) scioutfile.write("\n\n") except BrokenPipeError: # probably piped to head or tail return 0 return 0 if __name__ == "__main__": sys.exit(main(sys.argv)) geany-2.0/scripts/gen-signallist.sh0000754000175000017500000000031014514252267014346 00000000000000#!/bin/sh set -e HEADER="/* This file is auto-generated, do not edit. */" TEXT=$(sed -n 's/^.*handler="\([^"]\{1,\}\)".*$/ITEM(\1)/p' "$1" | sort | uniq) printf "%s\n%s\n" "$HEADER" "$TEXT" > "$2" geany-2.0/scripts/print-tags.py0000754000175000017500000000537014514252267013547 00000000000000#!/usr/bin/env python3 import sys # see tm_source_file.c TA_NAME, TA_LINE, TA_LOCAL, TA_POS, TA_TYPE, TA_ARGLIST, TA_SCOPE, \ TA_VARTYPE, TA_INHERITS, TA_TIME, TA_ACCESS, TA_IMPL, TA_LANG, \ TA_INACTIVE, TA_FLAGS = range(200, 215) # see TMTagType in tm_parser.h types = [ "undef", "class", "enum", "enumerator", "field", "function", "interface", "member", "method", "namespace", "package", "prototype", "struct", "typedef", "union", "variable", "externvar", "macro", "macro_arg", "file", "other", "UNKNOWN", "UNKNOWN", "UNKNOWN", "UNKNOWN", "UNKNOWN", "UNKNOWN", ] type_dct = {0: types[0]} for i in range(len(types) - 1): type_dct[1 << i] = types[i + 1] def decode_kind(kind, value): val = '' if kind == TA_NAME: val = value.decode('utf-8') elif kind == TA_LINE: val = int(value) elif kind == TA_LOCAL: val = int(value) elif kind == TA_TYPE: val = type_dct[int(value)] elif kind == TA_ARGLIST: val = value.decode('utf-8') elif kind == TA_SCOPE: val = value.decode('utf-8') elif kind == TA_FLAGS: val = int(value) elif kind == TA_VARTYPE: val = value.decode('utf-8') elif kind == TA_INHERITS: val = value.decode('utf-8') elif kind == TA_TIME: pass; elif kind == TA_LANG: pass; elif kind == TA_INACTIVE: pass; elif kind == TA_ACCESS: val = value.decode('utf-8') elif kind == TA_IMPL: val = value.decode('utf-8') return val def print_tag(tag): res = '{:<12}'.format(tag[TA_TYPE] + ': ') if TA_VARTYPE in tag: res += tag[TA_VARTYPE] + ' ' if TA_SCOPE in tag: res += tag[TA_SCOPE] + ' :: ' res += tag[TA_NAME] if TA_ARGLIST in tag: res += tag[TA_ARGLIST] if TA_INHERITS in tag: res += ' extends ' + tag[TA_INHERITS] if TA_FLAGS in tag and tag[TA_FLAGS] > 0: res += ' flags: ' + str(tag[TA_FLAGS]) # stdout.buffer (stdin.buffer) needed to write (read) binary data, see: # https://docs.python.org/3/library/sys.html?highlight=stdout#sys.stdout sys.stdout.buffer.write(res.encode('utf-8')) sys.stdout.buffer.write(b'\n') def get_next_part(inp, pos, first): part = b'' c = inp[pos] if first: kind = TA_NAME else: kind = c pos += 1 c = inp[pos] while c < TA_NAME and c != ord('\n'): part += bytes([c]) pos += 1 c = inp[pos] return part, kind, pos inp = sys.stdin.buffer.read() tag = {} pos = 0 line_start_pos = 0 line_start = True first_line = True while pos < len(inp): part, kind, pos = get_next_part(inp, pos, line_start) value = decode_kind(kind, part) tag[kind] = value line_start = False if inp[pos] == ord('\n'): if first_line: pass # first line contains '# format=tagmanager' we want to skip else: sys.stdout.buffer.write(inp[line_start_pos:pos]) sys.stdout.buffer.write(b'\n') print_tag(tag) first_line = False tag = {} pos += 1 line_start_pos = pos line_start = True geany-2.0/config.h.in0000644000175000017500000002247114514252332011431 00000000000000/* config.h.in. Generated from configure.ac by autoheader. */ /* Define to 1 if using 'alloca.c'. */ #undef C_ALLOCA /* Use AutoPackage? */ #undef ENABLE_BINRELOC /* Define to 1 if translation of program messages to the user's native language is requested. */ #undef ENABLE_NLS /* Gettext package. */ #undef GETTEXT_PACKAGE /* Define to 1 if you have 'alloca', as a function or macro. */ #undef HAVE_ALLOCA /* Define to 1 if works. */ #undef HAVE_ALLOCA_H /* Define to 1 if you have the `asprintf' function. */ #undef HAVE_ASPRINTF /* Define to 1 if you have the Mac OS X function CFLocaleCopyCurrent in the CoreFoundation framework. */ #undef HAVE_CFLOCALECOPYCURRENT /* Define to 1 if you have the Mac OS X function CFPreferencesCopyAppValue in the CoreFoundation framework. */ #undef HAVE_CFPREFERENCESCOPYAPPVALUE /* Define to 1 if you have the `chsize' function. */ #undef HAVE_CHSIZE /* define if the compiler supports basic C++17 syntax */ #undef HAVE_CXX17 /* Define if the GNU dcgettext() function is already present or preinstalled. */ #undef HAVE_DCGETTEXT /* Define to 1 if you have the declaration of `_NSGetEnviron', and to 0 if you don't. */ #undef HAVE_DECL__NSGETENVIRON /* Define to 1 if you have the declaration of `__environ', and to 0 if you don't. */ #undef HAVE_DECL___ENVIRON /* Define to 1 if you have the header file. */ #undef HAVE_DIRECT_H /* Define to 1 if you have the header file. */ #undef HAVE_DIRENT_H /* Define to 1 if you have the header file. */ #undef HAVE_DLFCN_H /* Define to 1 if you have the header file. */ #undef HAVE_ERRNO_H /* Define to 1 if you have the header file. */ #undef HAVE_FCNTL_H /* Define to 1 if you have the header file. */ #undef HAVE_FNMATCH_H /* Define to 1 if you have the `ftruncate' function. */ #undef HAVE_FTRUNCATE /* Define if the GNU gettext() function is already present or preinstalled. */ #undef HAVE_GETTEXT /* Define to 1 if you have the `g_strv_equal' function. */ #undef HAVE_G_STRV_EQUAL /* Define if you have the iconv() function and it works. */ #undef HAVE_ICONV /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_IO_H /* Define to 1 if you have the `isblank' function. */ #undef HAVE_ISBLANK /* Define to 1 if you have the header file. */ #undef HAVE_LANGINFO_H /* Define to 1 if you have the header file. */ #undef HAVE_LIBINTL_H /* Define to 1 if you have the header file. */ #undef HAVE_LIMITS_H /* Define to 1 if you have the header file. */ #undef HAVE_LOCALE_H /* Define to 1 if you have the `mbrtowc' function. */ #undef HAVE_MBRTOWC /* Define to 1 if you have the `memcpy' function. */ #undef HAVE_MEMCPY /* Define to 1 if you have the header file. */ #undef HAVE_MINIX_CONFIG_H /* Define to 1 if you have the `mkstemp' function. */ #undef HAVE_MKSTEMP /* Define if plugins are enabled. */ #undef HAVE_PLUGINS /* Define to 1 if you have the `realpath' function. */ #undef HAVE_REALPATH /* Should always be 1, required for CTags. */ #undef HAVE_REGCOMP /* Define if you want to detect a running instance */ #undef HAVE_SOCKET /* whether or not to use . */ #undef HAVE_STDBOOL_H /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDIO_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the `strcasecmp' function. */ #undef HAVE_STRCASECMP /* Define to 1 if you have the `strerror' function. */ #undef HAVE_STRERROR /* Define to 1 if you have the `stricmp' function. */ #undef HAVE_STRICMP /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Define to 1 if you have the `strncasecmp' function. */ #undef HAVE_STRNCASECMP /* Define to 1 if you have the `strnicmp' function. */ #undef HAVE_STRNICMP /* Define to 1 if you have the `strstr' function. */ #undef HAVE_STRSTR /* Define to 1 if you have the header file. */ #undef HAVE_SYS_DIR_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TIME_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if you have the `tempnam' function. */ #undef HAVE_TEMPNAM /* Define to 1 if you have the `truncate' function. */ #undef HAVE_TRUNCATE /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Define if you want VTE support */ #undef HAVE_VTE /* Define to 1 if you have the header file. */ #undef HAVE_WCHAR_H /* Define to 1 if you have the `wcrtomb' function. */ #undef HAVE_WCRTOMB /* Define to 1 if you have the `wcscoll' function. */ #undef HAVE_WCSCOLL /* Define to 1 if you have the header file. */ #undef HAVE_WCTYPE_H /* Define to the sub-directory where libtool stores uninstalled libraries. */ #undef LT_OBJDIR /* Name of package */ #undef PACKAGE /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the home page for this package. */ #undef PACKAGE_URL /* Define to the version of this package. */ #undef PACKAGE_VERSION /* git revision hash */ #undef REVISION /* If using the C implementation of alloca, define if you know the direction of stack growth for your system; otherwise it will be automatically deduced at runtime. STACK_DIRECTION > 0 => grows toward higher addresses STACK_DIRECTION < 0 => grows toward lower addresses STACK_DIRECTION = 0 => direction of growth unknown */ #undef STACK_DIRECTION /* Define to 1 if all of the C90 standard headers exist (not just the ones required in a freestanding environment). This macro is provided for backward compatibility; new code need not use it. */ #undef STDC_HEADERS /* Define to 1 if your declares `struct tm'. */ #undef TM_IN_SYS_TIME /* Enable extensions on AIX 3, Interix. */ #ifndef _ALL_SOURCE # undef _ALL_SOURCE #endif /* Enable general extensions on macOS. */ #ifndef _DARWIN_C_SOURCE # undef _DARWIN_C_SOURCE #endif /* Enable general extensions on Solaris. */ #ifndef __EXTENSIONS__ # undef __EXTENSIONS__ #endif /* Enable GNU extensions on systems that have them. */ #ifndef _GNU_SOURCE # undef _GNU_SOURCE #endif /* Enable X/Open compliant socket functions that do not require linking with -lxnet on HP-UX 11.11. */ #ifndef _HPUX_ALT_XOPEN_SOCKET_API # undef _HPUX_ALT_XOPEN_SOCKET_API #endif /* Identify the host operating system as Minix. This macro does not affect the system headers' behavior. A future release of Autoconf may stop defining this macro. */ #ifndef _MINIX # undef _MINIX #endif /* Enable general extensions on NetBSD. Enable NetBSD compatibility extensions on Minix. */ #ifndef _NETBSD_SOURCE # undef _NETBSD_SOURCE #endif /* Enable OpenBSD compatibility extensions on NetBSD. Oddly enough, this does nothing on OpenBSD. */ #ifndef _OPENBSD_SOURCE # undef _OPENBSD_SOURCE #endif /* Define to 1 if needed for POSIX-compatible behavior. */ #ifndef _POSIX_SOURCE # undef _POSIX_SOURCE #endif /* Define to 2 if needed for POSIX-compatible behavior. */ #ifndef _POSIX_1_SOURCE # undef _POSIX_1_SOURCE #endif /* Enable POSIX-compatible threading on Solaris. */ #ifndef _POSIX_PTHREAD_SEMANTICS # undef _POSIX_PTHREAD_SEMANTICS #endif /* Enable extensions specified by ISO/IEC TS 18661-5:2014. */ #ifndef __STDC_WANT_IEC_60559_ATTRIBS_EXT__ # undef __STDC_WANT_IEC_60559_ATTRIBS_EXT__ #endif /* Enable extensions specified by ISO/IEC TS 18661-1:2014. */ #ifndef __STDC_WANT_IEC_60559_BFP_EXT__ # undef __STDC_WANT_IEC_60559_BFP_EXT__ #endif /* Enable extensions specified by ISO/IEC TS 18661-2:2015. */ #ifndef __STDC_WANT_IEC_60559_DFP_EXT__ # undef __STDC_WANT_IEC_60559_DFP_EXT__ #endif /* Enable extensions specified by ISO/IEC TS 18661-4:2015. */ #ifndef __STDC_WANT_IEC_60559_FUNCS_EXT__ # undef __STDC_WANT_IEC_60559_FUNCS_EXT__ #endif /* Enable extensions specified by ISO/IEC TS 18661-3:2015. */ #ifndef __STDC_WANT_IEC_60559_TYPES_EXT__ # undef __STDC_WANT_IEC_60559_TYPES_EXT__ #endif /* Enable extensions specified by ISO/IEC TR 24731-2:2010. */ #ifndef __STDC_WANT_LIB_EXT2__ # undef __STDC_WANT_LIB_EXT2__ #endif /* Enable extensions specified by ISO/IEC 24747:2009. */ #ifndef __STDC_WANT_MATH_SPEC_FUNCS__ # undef __STDC_WANT_MATH_SPEC_FUNCS__ #endif /* Enable extensions on HP NonStop. */ #ifndef _TANDEM_SOURCE # undef _TANDEM_SOURCE #endif /* Enable X/Open extensions. Define to 500 only if necessary to make mbstate_t available. */ #ifndef _XOPEN_SOURCE # undef _XOPEN_SOURCE #endif /* Version number of package */ #undef VERSION /* Path to a loadable libvte */ #undef VTE_MODULE_PATH /* we are cross compiling for WIN32 */ #undef WIN32 /* Define to `long int' if does not define. */ #undef off_t /* Define to `unsigned int' if does not define. */ #undef size_t geany-2.0/build-aux/0000755000175000017500000000000014514253241011352 500000000000000geany-2.0/build-aux/config.sub0000754000175000017500000010511614514252334013262 00000000000000#! /bin/sh # Configuration validation subroutine script. # Copyright 1992-2022 Free Software Foundation, Inc. # shellcheck disable=SC2006,SC2268 # see below for rationale timestamp='2022-01-03' # This file 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, either version 3 of the License, or # (at your option) any later version. # # This program 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 . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # Please send patches to . # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # You can get the latest version of this script from: # https://git.savannah.gnu.org/cgit/config.git/plain/config.sub # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. # The "shellcheck disable" line above the timestamp inhibits complaints # about features and limitations of the classic Bourne shell that were # superseded or lifted in POSIX. However, this script identifies a wide # variety of pre-POSIX systems that do not have POSIX shells at all, and # even some reasonably current systems (Solaris 10 as case-in-point) still # have a pre-POSIX /bin/sh. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS Canonicalize a configuration name. Options: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.sub ($timestamp) Copyright 1992-2022 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; *local*) # First pass through any local machine types. echo "$1" exit ;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Split fields of configuration type # shellcheck disable=SC2162 saved_IFS=$IFS IFS="-" read field1 field2 field3 field4 <&2 exit 1 ;; *-*-*-*) basic_machine=$field1-$field2 basic_os=$field3-$field4 ;; *-*-*) # Ambiguous whether COMPANY is present, or skipped and KERNEL-OS is two # parts maybe_os=$field2-$field3 case $maybe_os in nto-qnx* | linux-* | uclinux-uclibc* \ | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* \ | netbsd*-eabi* | kopensolaris*-gnu* | cloudabi*-eabi* \ | storm-chaos* | os2-emx* | rtmk-nova*) basic_machine=$field1 basic_os=$maybe_os ;; android-linux) basic_machine=$field1-unknown basic_os=linux-android ;; *) basic_machine=$field1-$field2 basic_os=$field3 ;; esac ;; *-*) # A lone config we happen to match not fitting any pattern case $field1-$field2 in decstation-3100) basic_machine=mips-dec basic_os= ;; *-*) # Second component is usually, but not always the OS case $field2 in # Prevent following clause from handling this valid os sun*os*) basic_machine=$field1 basic_os=$field2 ;; zephyr*) basic_machine=$field1-unknown basic_os=$field2 ;; # Manufacturers dec* | mips* | sequent* | encore* | pc533* | sgi* | sony* \ | att* | 7300* | 3300* | delta* | motorola* | sun[234]* \ | unicom* | ibm* | next | hp | isi* | apollo | altos* \ | convergent* | ncr* | news | 32* | 3600* | 3100* \ | hitachi* | c[123]* | convex* | sun | crds | omron* | dg \ | ultra | tti* | harris | dolphin | highlevel | gould \ | cbm | ns | masscomp | apple | axis | knuth | cray \ | microblaze* | sim | cisco \ | oki | wec | wrs | winbond) basic_machine=$field1-$field2 basic_os= ;; *) basic_machine=$field1 basic_os=$field2 ;; esac ;; esac ;; *) # Convert single-component short-hands not valid as part of # multi-component configurations. case $field1 in 386bsd) basic_machine=i386-pc basic_os=bsd ;; a29khif) basic_machine=a29k-amd basic_os=udi ;; adobe68k) basic_machine=m68010-adobe basic_os=scout ;; alliant) basic_machine=fx80-alliant basic_os= ;; altos | altos3068) basic_machine=m68k-altos basic_os= ;; am29k) basic_machine=a29k-none basic_os=bsd ;; amdahl) basic_machine=580-amdahl basic_os=sysv ;; amiga) basic_machine=m68k-unknown basic_os= ;; amigaos | amigados) basic_machine=m68k-unknown basic_os=amigaos ;; amigaunix | amix) basic_machine=m68k-unknown basic_os=sysv4 ;; apollo68) basic_machine=m68k-apollo basic_os=sysv ;; apollo68bsd) basic_machine=m68k-apollo basic_os=bsd ;; aros) basic_machine=i386-pc basic_os=aros ;; aux) basic_machine=m68k-apple basic_os=aux ;; balance) basic_machine=ns32k-sequent basic_os=dynix ;; blackfin) basic_machine=bfin-unknown basic_os=linux ;; cegcc) basic_machine=arm-unknown basic_os=cegcc ;; convex-c1) basic_machine=c1-convex basic_os=bsd ;; convex-c2) basic_machine=c2-convex basic_os=bsd ;; convex-c32) basic_machine=c32-convex basic_os=bsd ;; convex-c34) basic_machine=c34-convex basic_os=bsd ;; convex-c38) basic_machine=c38-convex basic_os=bsd ;; cray) basic_machine=j90-cray basic_os=unicos ;; crds | unos) basic_machine=m68k-crds basic_os= ;; da30) basic_machine=m68k-da30 basic_os= ;; decstation | pmax | pmin | dec3100 | decstatn) basic_machine=mips-dec basic_os= ;; delta88) basic_machine=m88k-motorola basic_os=sysv3 ;; dicos) basic_machine=i686-pc basic_os=dicos ;; djgpp) basic_machine=i586-pc basic_os=msdosdjgpp ;; ebmon29k) basic_machine=a29k-amd basic_os=ebmon ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson basic_os=ose ;; gmicro) basic_machine=tron-gmicro basic_os=sysv ;; go32) basic_machine=i386-pc basic_os=go32 ;; h8300hms) basic_machine=h8300-hitachi basic_os=hms ;; h8300xray) basic_machine=h8300-hitachi basic_os=xray ;; h8500hms) basic_machine=h8500-hitachi basic_os=hms ;; harris) basic_machine=m88k-harris basic_os=sysv3 ;; hp300 | hp300hpux) basic_machine=m68k-hp basic_os=hpux ;; hp300bsd) basic_machine=m68k-hp basic_os=bsd ;; hppaosf) basic_machine=hppa1.1-hp basic_os=osf ;; hppro) basic_machine=hppa1.1-hp basic_os=proelf ;; i386mach) basic_machine=i386-mach basic_os=mach ;; isi68 | isi) basic_machine=m68k-isi basic_os=sysv ;; m68knommu) basic_machine=m68k-unknown basic_os=linux ;; magnum | m3230) basic_machine=mips-mips basic_os=sysv ;; merlin) basic_machine=ns32k-utek basic_os=sysv ;; mingw64) basic_machine=x86_64-pc basic_os=mingw64 ;; mingw32) basic_machine=i686-pc basic_os=mingw32 ;; mingw32ce) basic_machine=arm-unknown basic_os=mingw32ce ;; monitor) basic_machine=m68k-rom68k basic_os=coff ;; morphos) basic_machine=powerpc-unknown basic_os=morphos ;; moxiebox) basic_machine=moxie-unknown basic_os=moxiebox ;; msdos) basic_machine=i386-pc basic_os=msdos ;; msys) basic_machine=i686-pc basic_os=msys ;; mvs) basic_machine=i370-ibm basic_os=mvs ;; nacl) basic_machine=le32-unknown basic_os=nacl ;; ncr3000) basic_machine=i486-ncr basic_os=sysv4 ;; netbsd386) basic_machine=i386-pc basic_os=netbsd ;; netwinder) basic_machine=armv4l-rebel basic_os=linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony basic_os=newsos ;; news1000) basic_machine=m68030-sony basic_os=newsos ;; necv70) basic_machine=v70-nec basic_os=sysv ;; nh3000) basic_machine=m68k-harris basic_os=cxux ;; nh[45]000) basic_machine=m88k-harris basic_os=cxux ;; nindy960) basic_machine=i960-intel basic_os=nindy ;; mon960) basic_machine=i960-intel basic_os=mon960 ;; nonstopux) basic_machine=mips-compaq basic_os=nonstopux ;; os400) basic_machine=powerpc-ibm basic_os=os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson basic_os=ose ;; os68k) basic_machine=m68k-none basic_os=os68k ;; paragon) basic_machine=i860-intel basic_os=osf ;; parisc) basic_machine=hppa-unknown basic_os=linux ;; psp) basic_machine=mipsallegrexel-sony basic_os=psp ;; pw32) basic_machine=i586-unknown basic_os=pw32 ;; rdos | rdos64) basic_machine=x86_64-pc basic_os=rdos ;; rdos32) basic_machine=i386-pc basic_os=rdos ;; rom68k) basic_machine=m68k-rom68k basic_os=coff ;; sa29200) basic_machine=a29k-amd basic_os=udi ;; sei) basic_machine=mips-sei basic_os=seiux ;; sequent) basic_machine=i386-sequent basic_os= ;; sps7) basic_machine=m68k-bull basic_os=sysv2 ;; st2000) basic_machine=m68k-tandem basic_os= ;; stratus) basic_machine=i860-stratus basic_os=sysv4 ;; sun2) basic_machine=m68000-sun basic_os= ;; sun2os3) basic_machine=m68000-sun basic_os=sunos3 ;; sun2os4) basic_machine=m68000-sun basic_os=sunos4 ;; sun3) basic_machine=m68k-sun basic_os= ;; sun3os3) basic_machine=m68k-sun basic_os=sunos3 ;; sun3os4) basic_machine=m68k-sun basic_os=sunos4 ;; sun4) basic_machine=sparc-sun basic_os= ;; sun4os3) basic_machine=sparc-sun basic_os=sunos3 ;; sun4os4) basic_machine=sparc-sun basic_os=sunos4 ;; sun4sol2) basic_machine=sparc-sun basic_os=solaris2 ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun basic_os= ;; sv1) basic_machine=sv1-cray basic_os=unicos ;; symmetry) basic_machine=i386-sequent basic_os=dynix ;; t3e) basic_machine=alphaev5-cray basic_os=unicos ;; t90) basic_machine=t90-cray basic_os=unicos ;; toad1) basic_machine=pdp10-xkl basic_os=tops20 ;; tpf) basic_machine=s390x-ibm basic_os=tpf ;; udi29k) basic_machine=a29k-amd basic_os=udi ;; ultra3) basic_machine=a29k-nyu basic_os=sym1 ;; v810 | necv810) basic_machine=v810-nec basic_os=none ;; vaxv) basic_machine=vax-dec basic_os=sysv ;; vms) basic_machine=vax-dec basic_os=vms ;; vsta) basic_machine=i386-pc basic_os=vsta ;; vxworks960) basic_machine=i960-wrs basic_os=vxworks ;; vxworks68) basic_machine=m68k-wrs basic_os=vxworks ;; vxworks29k) basic_machine=a29k-wrs basic_os=vxworks ;; xbox) basic_machine=i686-pc basic_os=mingw32 ;; ymp) basic_machine=ymp-cray basic_os=unicos ;; *) basic_machine=$1 basic_os= ;; esac ;; esac # Decode 1-component or ad-hoc basic machines case $basic_machine in # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) cpu=hppa1.1 vendor=winbond ;; op50n) cpu=hppa1.1 vendor=oki ;; op60c) cpu=hppa1.1 vendor=oki ;; ibm*) cpu=i370 vendor=ibm ;; orion105) cpu=clipper vendor=highlevel ;; mac | mpw | mac-mpw) cpu=m68k vendor=apple ;; pmac | pmac-mpw) cpu=powerpc vendor=apple ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) cpu=m68000 vendor=att ;; 3b*) cpu=we32k vendor=att ;; bluegene*) cpu=powerpc vendor=ibm basic_os=cnk ;; decsystem10* | dec10*) cpu=pdp10 vendor=dec basic_os=tops10 ;; decsystem20* | dec20*) cpu=pdp10 vendor=dec basic_os=tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) cpu=m68k vendor=motorola ;; dpx2*) cpu=m68k vendor=bull basic_os=sysv3 ;; encore | umax | mmax) cpu=ns32k vendor=encore ;; elxsi) cpu=elxsi vendor=elxsi basic_os=${basic_os:-bsd} ;; fx2800) cpu=i860 vendor=alliant ;; genix) cpu=ns32k vendor=ns ;; h3050r* | hiux*) cpu=hppa1.1 vendor=hitachi basic_os=hiuxwe2 ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) cpu=hppa1.0 vendor=hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) cpu=m68000 vendor=hp ;; hp9k3[2-9][0-9]) cpu=m68k vendor=hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) cpu=hppa1.0 vendor=hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) cpu=hppa1.1 vendor=hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp cpu=hppa1.1 vendor=hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp cpu=hppa1.1 vendor=hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) cpu=hppa1.1 vendor=hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) cpu=hppa1.0 vendor=hp ;; i*86v32) cpu=`echo "$1" | sed -e 's/86.*/86/'` vendor=pc basic_os=sysv32 ;; i*86v4*) cpu=`echo "$1" | sed -e 's/86.*/86/'` vendor=pc basic_os=sysv4 ;; i*86v) cpu=`echo "$1" | sed -e 's/86.*/86/'` vendor=pc basic_os=sysv ;; i*86sol2) cpu=`echo "$1" | sed -e 's/86.*/86/'` vendor=pc basic_os=solaris2 ;; j90 | j90-cray) cpu=j90 vendor=cray basic_os=${basic_os:-unicos} ;; iris | iris4d) cpu=mips vendor=sgi case $basic_os in irix*) ;; *) basic_os=irix4 ;; esac ;; miniframe) cpu=m68000 vendor=convergent ;; *mint | mint[0-9]* | *MiNT | *MiNT[0-9]*) cpu=m68k vendor=atari basic_os=mint ;; news-3600 | risc-news) cpu=mips vendor=sony basic_os=newsos ;; next | m*-next) cpu=m68k vendor=next case $basic_os in openstep*) ;; nextstep*) ;; ns2*) basic_os=nextstep2 ;; *) basic_os=nextstep3 ;; esac ;; np1) cpu=np1 vendor=gould ;; op50n-* | op60c-*) cpu=hppa1.1 vendor=oki basic_os=proelf ;; pa-hitachi) cpu=hppa1.1 vendor=hitachi basic_os=hiuxwe2 ;; pbd) cpu=sparc vendor=tti ;; pbb) cpu=m68k vendor=tti ;; pc532) cpu=ns32k vendor=pc532 ;; pn) cpu=pn vendor=gould ;; power) cpu=power vendor=ibm ;; ps2) cpu=i386 vendor=ibm ;; rm[46]00) cpu=mips vendor=siemens ;; rtpc | rtpc-*) cpu=romp vendor=ibm ;; sde) cpu=mipsisa32 vendor=sde basic_os=${basic_os:-elf} ;; simso-wrs) cpu=sparclite vendor=wrs basic_os=vxworks ;; tower | tower-32) cpu=m68k vendor=ncr ;; vpp*|vx|vx-*) cpu=f301 vendor=fujitsu ;; w65) cpu=w65 vendor=wdc ;; w89k-*) cpu=hppa1.1 vendor=winbond basic_os=proelf ;; none) cpu=none vendor=none ;; leon|leon[3-9]) cpu=sparc vendor=$basic_machine ;; leon-*|leon[3-9]-*) cpu=sparc vendor=`echo "$basic_machine" | sed 's/-.*//'` ;; *-*) # shellcheck disable=SC2162 saved_IFS=$IFS IFS="-" read cpu vendor <&2 exit 1 ;; esac ;; esac # Here we canonicalize certain aliases for manufacturers. case $vendor in digital*) vendor=dec ;; commodore*) vendor=cbm ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if test x$basic_os != x then # First recognize some ad-hoc cases, or perhaps split kernel-os, or else just # set os. case $basic_os in gnu/linux*) kernel=linux os=`echo "$basic_os" | sed -e 's|gnu/linux|gnu|'` ;; os2-emx) kernel=os2 os=`echo "$basic_os" | sed -e 's|os2-emx|emx|'` ;; nto-qnx*) kernel=nto os=`echo "$basic_os" | sed -e 's|nto-qnx|qnx|'` ;; *-*) # shellcheck disable=SC2162 saved_IFS=$IFS IFS="-" read kernel os <&2 exit 1 ;; esac # As a final step for OS-related things, validate the OS-kernel combination # (given a valid OS), if there is a kernel. case $kernel-$os in linux-gnu* | linux-dietlibc* | linux-android* | linux-newlib* \ | linux-musl* | linux-relibc* | linux-uclibc* ) ;; uclinux-uclibc* ) ;; -dietlibc* | -newlib* | -musl* | -relibc* | -uclibc* ) # These are just libc implementations, not actual OSes, and thus # require a kernel. echo "Invalid configuration \`$1': libc \`$os' needs explicit kernel." 1>&2 exit 1 ;; kfreebsd*-gnu* | kopensolaris*-gnu*) ;; vxworks-simlinux | vxworks-simwindows | vxworks-spe) ;; nto-qnx*) ;; os2-emx) ;; *-eabi* | *-gnueabi*) ;; -*) # Blank kernel with real OS is always fine. ;; *-*) echo "Invalid configuration \`$1': Kernel \`$kernel' not known to work with OS \`$os'." 1>&2 exit 1 ;; esac # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. case $vendor in unknown) case $cpu-$os in *-riscix*) vendor=acorn ;; *-sunos*) vendor=sun ;; *-cnk* | *-aix*) vendor=ibm ;; *-beos*) vendor=be ;; *-hpux*) vendor=hp ;; *-mpeix*) vendor=hp ;; *-hiux*) vendor=hitachi ;; *-unos*) vendor=crds ;; *-dgux*) vendor=dg ;; *-luna*) vendor=omron ;; *-genix*) vendor=ns ;; *-clix*) vendor=intergraph ;; *-mvs* | *-opened*) vendor=ibm ;; *-os400*) vendor=ibm ;; s390-* | s390x-*) vendor=ibm ;; *-ptx*) vendor=sequent ;; *-tpf*) vendor=ibm ;; *-vxsim* | *-vxworks* | *-windiss*) vendor=wrs ;; *-aux*) vendor=apple ;; *-hms*) vendor=hitachi ;; *-mpw* | *-macos*) vendor=apple ;; *-*mint | *-mint[0-9]* | *-*MiNT | *-MiNT[0-9]*) vendor=atari ;; *-vos*) vendor=stratus ;; esac ;; esac echo "$cpu-$vendor-${kernel:+$kernel-}$os" exit # Local variables: # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: geany-2.0/build-aux/compile0000754000175000017500000001635014514252334012656 00000000000000#! /bin/sh # Wrapper for compilers which do not understand '-c -o'. scriptversion=2018-03-07.03; # UTC # Copyright (C) 1999-2021 Free Software Foundation, Inc. # Written by Tom Tromey . # # This program 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; either version 2, or (at your option) # any later version. # # This program 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 . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # This file is maintained in Automake, please report # bugs to or send patches to # . nl=' ' # We need space, tab and new line, in precisely that order. Quoting is # there to prevent tools from complaining about whitespace usage. IFS=" "" $nl" file_conv= # func_file_conv build_file lazy # Convert a $build file to $host form and store it in $file # Currently only supports Windows hosts. If the determined conversion # type is listed in (the comma separated) LAZY, no conversion will # take place. func_file_conv () { file=$1 case $file in / | /[!/]*) # absolute file, and not a UNC file if test -z "$file_conv"; then # lazily determine how to convert abs files case `uname -s` in MINGW*) file_conv=mingw ;; CYGWIN* | MSYS*) file_conv=cygwin ;; *) file_conv=wine ;; esac fi case $file_conv/,$2, in *,$file_conv,*) ;; mingw/*) file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` ;; cygwin/* | msys/*) file=`cygpath -m "$file" || echo "$file"` ;; wine/*) file=`winepath -w "$file" || echo "$file"` ;; esac ;; esac } # func_cl_dashL linkdir # Make cl look for libraries in LINKDIR func_cl_dashL () { func_file_conv "$1" if test -z "$lib_path"; then lib_path=$file else lib_path="$lib_path;$file" fi linker_opts="$linker_opts -LIBPATH:$file" } # func_cl_dashl library # Do a library search-path lookup for cl func_cl_dashl () { lib=$1 found=no save_IFS=$IFS IFS=';' for dir in $lib_path $LIB do IFS=$save_IFS if $shared && test -f "$dir/$lib.dll.lib"; then found=yes lib=$dir/$lib.dll.lib break fi if test -f "$dir/$lib.lib"; then found=yes lib=$dir/$lib.lib break fi if test -f "$dir/lib$lib.a"; then found=yes lib=$dir/lib$lib.a break fi done IFS=$save_IFS if test "$found" != yes; then lib=$lib.lib fi } # func_cl_wrapper cl arg... # Adjust compile command to suit cl func_cl_wrapper () { # Assume a capable shell lib_path= shared=: linker_opts= for arg do if test -n "$eat"; then eat= else case $1 in -o) # configure might choose to run compile as 'compile cc -o foo foo.c'. eat=1 case $2 in *.o | *.[oO][bB][jJ]) func_file_conv "$2" set x "$@" -Fo"$file" shift ;; *) func_file_conv "$2" set x "$@" -Fe"$file" shift ;; esac ;; -I) eat=1 func_file_conv "$2" mingw set x "$@" -I"$file" shift ;; -I*) func_file_conv "${1#-I}" mingw set x "$@" -I"$file" shift ;; -l) eat=1 func_cl_dashl "$2" set x "$@" "$lib" shift ;; -l*) func_cl_dashl "${1#-l}" set x "$@" "$lib" shift ;; -L) eat=1 func_cl_dashL "$2" ;; -L*) func_cl_dashL "${1#-L}" ;; -static) shared=false ;; -Wl,*) arg=${1#-Wl,} save_ifs="$IFS"; IFS=',' for flag in $arg; do IFS="$save_ifs" linker_opts="$linker_opts $flag" done IFS="$save_ifs" ;; -Xlinker) eat=1 linker_opts="$linker_opts $2" ;; -*) set x "$@" "$1" shift ;; *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) func_file_conv "$1" set x "$@" -Tp"$file" shift ;; *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) func_file_conv "$1" mingw set x "$@" "$file" shift ;; *) set x "$@" "$1" shift ;; esac fi shift done if test -n "$linker_opts"; then linker_opts="-link$linker_opts" fi exec "$@" $linker_opts exit 1 } eat= case $1 in '') echo "$0: No command. Try '$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: compile [--help] [--version] PROGRAM [ARGS] Wrapper for compilers which do not understand '-c -o'. Remove '-o dest.o' from ARGS, run PROGRAM with the remaining arguments, and rename the output as expected. If you are trying to build a whole package this is not the right script to run: please start by reading the file 'INSTALL'. Report bugs to . EOF exit $? ;; -v | --v*) echo "compile $scriptversion" exit $? ;; cl | *[/\\]cl | cl.exe | *[/\\]cl.exe | \ icl | *[/\\]icl | icl.exe | *[/\\]icl.exe ) func_cl_wrapper "$@" # Doesn't return... ;; esac ofile= cfile= for arg do if test -n "$eat"; then eat= else case $1 in -o) # configure might choose to run compile as 'compile cc -o foo foo.c'. # So we strip '-o arg' only if arg is an object. eat=1 case $2 in *.o | *.obj) ofile=$2 ;; *) set x "$@" -o "$2" shift ;; esac ;; *.c) cfile=$1 set x "$@" "$1" shift ;; *) set x "$@" "$1" shift ;; esac fi shift done if test -z "$ofile" || test -z "$cfile"; then # If no '-o' option was seen then we might have been invoked from a # pattern rule where we don't need one. That is ok -- this is a # normal compilation that the losing compiler can handle. If no # '.c' file was seen then we are probably linking. That is also # ok. exec "$@" fi # Name of file we expect compiler to create. cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` # Create the lock directory. # Note: use '[/\\:.-]' here to ensure that we don't use the same name # that we are using for the .o file. Also, base the name on the expected # object file name, since that is what matters with a parallel build. lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d while true; do if mkdir "$lockdir" >/dev/null 2>&1; then break fi sleep 1 done # FIXME: race condition here if user kills between mkdir and trap. trap "rmdir '$lockdir'; exit 1" 1 2 15 # Run the compile. "$@" ret=$? if test -f "$cofile"; then test "$cofile" = "$ofile" || mv "$cofile" "$ofile" elif test -f "${cofile}bj"; then test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" fi rmdir "$lockdir" exit $ret # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: geany-2.0/build-aux/missing0000754000175000017500000001533614514252334012702 00000000000000#! /bin/sh # Common wrapper for a few potentially missing GNU programs. scriptversion=2018-03-07.03; # UTC # Copyright (C) 1996-2021 Free Software Foundation, Inc. # Originally written by Fran,cois Pinard , 1996. # This program 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; either version 2, or (at your option) # any later version. # This program 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 . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then echo 1>&2 "Try '$0 --help' for more information" exit 1 fi case $1 in --is-lightweight) # Used by our autoconf macros to check whether the available missing # script is modern enough. exit 0 ;; --run) # Back-compat with the calling convention used by older automake. shift ;; -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due to PROGRAM being missing or too old. Options: -h, --help display this help and exit -v, --version output version information and exit Supported PROGRAM values: aclocal autoconf autoheader autom4te automake makeinfo bison yacc flex lex help2man Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and 'g' are ignored when checking the name. Send bug reports to ." exit $? ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) echo "missing $scriptversion (GNU Automake)" exit $? ;; -*) echo 1>&2 "$0: unknown '$1' option" echo 1>&2 "Try '$0 --help' for more information" exit 1 ;; esac # Run the given program, remember its exit status. "$@"; st=$? # If it succeeded, we are done. test $st -eq 0 && exit 0 # Also exit now if we it failed (or wasn't found), and '--version' was # passed; such an option is passed most likely to detect whether the # program is present and works. case $2 in --version|--help) exit $st;; esac # Exit code 63 means version mismatch. This often happens when the user # tries to use an ancient version of a tool on a file that requires a # minimum version. if test $st -eq 63; then msg="probably too old" elif test $st -eq 127; then # Program was missing. msg="missing on your system" else # Program was found and executed, but failed. Give up. exit $st fi perl_URL=https://www.perl.org/ flex_URL=https://github.com/westes/flex gnu_software_URL=https://www.gnu.org/software program_details () { case $1 in aclocal|automake) echo "The '$1' program is part of the GNU Automake package:" echo "<$gnu_software_URL/automake>" echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:" echo "<$gnu_software_URL/autoconf>" echo "<$gnu_software_URL/m4/>" echo "<$perl_URL>" ;; autoconf|autom4te|autoheader) echo "The '$1' program is part of the GNU Autoconf package:" echo "<$gnu_software_URL/autoconf/>" echo "It also requires GNU m4 and Perl in order to run:" echo "<$gnu_software_URL/m4/>" echo "<$perl_URL>" ;; esac } give_advice () { # Normalize program name to check for. normalized_program=`echo "$1" | sed ' s/^gnu-//; t s/^gnu//; t s/^g//; t'` printf '%s\n' "'$1' is $msg." configure_deps="'configure.ac' or m4 files included by 'configure.ac'" case $normalized_program in autoconf*) echo "You should only need it if you modified 'configure.ac'," echo "or m4 files included by it." program_details 'autoconf' ;; autoheader*) echo "You should only need it if you modified 'acconfig.h' or" echo "$configure_deps." program_details 'autoheader' ;; automake*) echo "You should only need it if you modified 'Makefile.am' or" echo "$configure_deps." program_details 'automake' ;; aclocal*) echo "You should only need it if you modified 'acinclude.m4' or" echo "$configure_deps." program_details 'aclocal' ;; autom4te*) echo "You might have modified some maintainer files that require" echo "the 'autom4te' program to be rebuilt." program_details 'autom4te' ;; bison*|yacc*) echo "You should only need it if you modified a '.y' file." echo "You may want to install the GNU Bison package:" echo "<$gnu_software_URL/bison/>" ;; lex*|flex*) echo "You should only need it if you modified a '.l' file." echo "You may want to install the Fast Lexical Analyzer package:" echo "<$flex_URL>" ;; help2man*) echo "You should only need it if you modified a dependency" \ "of a man page." echo "You may want to install the GNU Help2man package:" echo "<$gnu_software_URL/help2man/>" ;; makeinfo*) echo "You should only need it if you modified a '.texi' file, or" echo "any other file indirectly affecting the aspect of the manual." echo "You might want to install the Texinfo package:" echo "<$gnu_software_URL/texinfo/>" echo "The spurious makeinfo call might also be the consequence of" echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might" echo "want to install GNU make:" echo "<$gnu_software_URL/make/>" ;; *) echo "You might have modified some files without having the proper" echo "tools for further handling them. Check the 'README' file, it" echo "often tells you about the needed prerequisites for installing" echo "this package. You may also peek at any GNU archive site, in" echo "case some other package contains this missing '$1' program." ;; esac } give_advice "$1" | sed -e '1s/^/WARNING: /' \ -e '2,$s/^/ /' >&2 # Propagate the correct exit status (expected to be 127 for a program # not found, 63 for a program that failed due to version mismatch). exit $st # Local variables: # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: geany-2.0/build-aux/config.guess0000754000175000017500000014051214514252334013616 00000000000000#! /bin/sh # Attempt to guess a canonical system name. # Copyright 1992-2022 Free Software Foundation, Inc. # shellcheck disable=SC2006,SC2268 # see below for rationale timestamp='2022-01-09' # This file 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, either version 3 of the License, or # (at your option) any later version. # # This program 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 . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # # Originally written by Per Bothner; maintained since 2000 by Ben Elliston. # # You can get the latest version of this script from: # https://git.savannah.gnu.org/cgit/config.git/plain/config.guess # # Please send patches to . # The "shellcheck disable" line above the timestamp inhibits complaints # about features and limitations of the classic Bourne shell that were # superseded or lifted in POSIX. However, this script identifies a wide # variety of pre-POSIX systems that do not have POSIX shells at all, and # even some reasonably current systems (Solaris 10 as case-in-point) still # have a pre-POSIX /bin/sh. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. Options: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright 1992-2022 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi # Just in case it came from the environment. GUESS= # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still # use `HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. tmp= # shellcheck disable=SC2172 trap 'test -z "$tmp" || rm -fr "$tmp"' 0 1 2 13 15 set_cc_for_build() { # prevent multiple calls if $tmp is already set test "$tmp" && return 0 : "${TMPDIR=/tmp}" # shellcheck disable=SC2039,SC3028 { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir "$tmp" 2>/dev/null) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir "$tmp" 2>/dev/null) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } dummy=$tmp/dummy case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in ,,) echo "int x;" > "$dummy.c" for driver in cc gcc c89 c99 ; do if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then CC_FOR_BUILD=$driver break fi done if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac } # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) if test -f /.attbin/uname ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown case $UNAME_SYSTEM in Linux|GNU|GNU/*) LIBC=unknown set_cc_for_build cat <<-EOF > "$dummy.c" #include #if defined(__UCLIBC__) LIBC=uclibc #elif defined(__dietlibc__) LIBC=dietlibc #elif defined(__GLIBC__) LIBC=gnu #else #include /* First heuristic to detect musl libc. */ #ifdef __DEFINED_va_list LIBC=musl #endif #endif EOF cc_set_libc=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` eval "$cc_set_libc" # Second heuristic to detect musl libc. if [ "$LIBC" = unknown ] && command -v ldd >/dev/null && ldd --version 2>&1 | grep -q ^musl; then LIBC=musl fi # If the system lacks a compiler, then just pick glibc. # We could probably try harder. if [ "$LIBC" = unknown ]; then LIBC=gnu fi ;; esac # Note: order is significant - the case branches are not exclusive. case $UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ /sbin/sysctl -n hw.machine_arch 2>/dev/null || \ /usr/sbin/sysctl -n hw.machine_arch 2>/dev/null || \ echo unknown)` case $UNAME_MACHINE_ARCH in aarch64eb) machine=aarch64_be-unknown ;; armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; earmv*) arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'` endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'` machine=${arch}${endian}-unknown ;; *) machine=$UNAME_MACHINE_ARCH-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently (or will in the future) and ABI. case $UNAME_MACHINE_ARCH in earm*) os=netbsdelf ;; arm*|i386|m68k|ns32k|sh3*|sparc|vax) set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # Determine ABI tags. case $UNAME_MACHINE_ARCH in earm*) expr='s/^earmv[0-9]/-eabi/;s/eb$//' abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"` ;; esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. case $UNAME_VERSION in Debian*) release='-gnu' ;; *) release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. GUESS=$machine-${os}${release}${abi-} ;; *:Bitrig:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` GUESS=$UNAME_MACHINE_ARCH-unknown-bitrig$UNAME_RELEASE ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` GUESS=$UNAME_MACHINE_ARCH-unknown-openbsd$UNAME_RELEASE ;; *:SecBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/SecBSD.//'` GUESS=$UNAME_MACHINE_ARCH-unknown-secbsd$UNAME_RELEASE ;; *:LibertyBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` GUESS=$UNAME_MACHINE_ARCH-unknown-libertybsd$UNAME_RELEASE ;; *:MidnightBSD:*:*) GUESS=$UNAME_MACHINE-unknown-midnightbsd$UNAME_RELEASE ;; *:ekkoBSD:*:*) GUESS=$UNAME_MACHINE-unknown-ekkobsd$UNAME_RELEASE ;; *:SolidBSD:*:*) GUESS=$UNAME_MACHINE-unknown-solidbsd$UNAME_RELEASE ;; *:OS108:*:*) GUESS=$UNAME_MACHINE-unknown-os108_$UNAME_RELEASE ;; macppc:MirBSD:*:*) GUESS=powerpc-unknown-mirbsd$UNAME_RELEASE ;; *:MirBSD:*:*) GUESS=$UNAME_MACHINE-unknown-mirbsd$UNAME_RELEASE ;; *:Sortix:*:*) GUESS=$UNAME_MACHINE-unknown-sortix ;; *:Twizzler:*:*) GUESS=$UNAME_MACHINE-unknown-twizzler ;; *:Redox:*:*) GUESS=$UNAME_MACHINE-unknown-redox ;; mips:OSF1:*.*) GUESS=mips-dec-osf1 ;; alpha:OSF1:*:*) # Reset EXIT trap before exiting to avoid spurious non-zero exit code. trap '' 0 case $UNAME_RELEASE in *4.0) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ;; *5.*) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case $ALPHA_CPU_TYPE in "EV4 (21064)") UNAME_MACHINE=alpha ;; "EV4.5 (21064)") UNAME_MACHINE=alpha ;; "LCA4 (21066/21068)") UNAME_MACHINE=alpha ;; "EV5 (21164)") UNAME_MACHINE=alphaev5 ;; "EV5.6 (21164A)") UNAME_MACHINE=alphaev56 ;; "EV5.6 (21164PC)") UNAME_MACHINE=alphapca56 ;; "EV5.7 (21164PC)") UNAME_MACHINE=alphapca57 ;; "EV6 (21264)") UNAME_MACHINE=alphaev6 ;; "EV6.7 (21264A)") UNAME_MACHINE=alphaev67 ;; "EV6.8CB (21264C)") UNAME_MACHINE=alphaev68 ;; "EV6.8AL (21264B)") UNAME_MACHINE=alphaev68 ;; "EV6.8CX (21264D)") UNAME_MACHINE=alphaev68 ;; "EV6.9A (21264/EV69A)") UNAME_MACHINE=alphaev69 ;; "EV7 (21364)") UNAME_MACHINE=alphaev7 ;; "EV7.9 (21364A)") UNAME_MACHINE=alphaev79 ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. OSF_REL=`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` GUESS=$UNAME_MACHINE-dec-osf$OSF_REL ;; Amiga*:UNIX_System_V:4.0:*) GUESS=m68k-unknown-sysv4 ;; *:[Aa]miga[Oo][Ss]:*:*) GUESS=$UNAME_MACHINE-unknown-amigaos ;; *:[Mm]orph[Oo][Ss]:*:*) GUESS=$UNAME_MACHINE-unknown-morphos ;; *:OS/390:*:*) GUESS=i370-ibm-openedition ;; *:z/VM:*:*) GUESS=s390-ibm-zvmoe ;; *:OS400:*:*) GUESS=powerpc-ibm-os400 ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) GUESS=arm-acorn-riscix$UNAME_RELEASE ;; arm*:riscos:*:*|arm*:RISCOS:*:*) GUESS=arm-unknown-riscos ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) GUESS=hppa1.1-hitachi-hiuxmpp ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. case `(/bin/universe) 2>/dev/null` in att) GUESS=pyramid-pyramid-sysv3 ;; *) GUESS=pyramid-pyramid-bsd ;; esac ;; NILE*:*:*:dcosx) GUESS=pyramid-pyramid-svr4 ;; DRS?6000:unix:4.0:6*) GUESS=sparc-icl-nx6 ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) case `/usr/bin/uname -p` in sparc) GUESS=sparc-icl-nx7 ;; esac ;; s390x:SunOS:*:*) SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` GUESS=$UNAME_MACHINE-ibm-solaris2$SUN_REL ;; sun4H:SunOS:5.*:*) SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` GUESS=sparc-hal-solaris2$SUN_REL ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` GUESS=sparc-sun-solaris2$SUN_REL ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) GUESS=i386-pc-auroraux$UNAME_RELEASE ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) set_cc_for_build SUN_ARCH=i386 # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. if test "$CC_FOR_BUILD" != no_compiler_found; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -m64 -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then SUN_ARCH=x86_64 fi fi SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` GUESS=$SUN_ARCH-pc-solaris2$SUN_REL ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` GUESS=sparc-sun-solaris3$SUN_REL ;; sun4*:SunOS:*:*) case `/usr/bin/arch -k` in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/'` GUESS=sparc-sun-sunos$SUN_REL ;; sun3*:SunOS:*:*) GUESS=m68k-sun-sunos$UNAME_RELEASE ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3 case `/bin/arch` in sun3) GUESS=m68k-sun-sunos$UNAME_RELEASE ;; sun4) GUESS=sparc-sun-sunos$UNAME_RELEASE ;; esac ;; aushp:SunOS:*:*) GUESS=sparc-auspex-sunos$UNAME_RELEASE ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) GUESS=m68k-atari-mint$UNAME_RELEASE ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) GUESS=m68k-atari-mint$UNAME_RELEASE ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) GUESS=m68k-atari-mint$UNAME_RELEASE ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) GUESS=m68k-milan-mint$UNAME_RELEASE ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) GUESS=m68k-hades-mint$UNAME_RELEASE ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) GUESS=m68k-unknown-mint$UNAME_RELEASE ;; m68k:machten:*:*) GUESS=m68k-apple-machten$UNAME_RELEASE ;; powerpc:machten:*:*) GUESS=powerpc-apple-machten$UNAME_RELEASE ;; RISC*:Mach:*:*) GUESS=mips-dec-mach_bsd4.3 ;; RISC*:ULTRIX:*:*) GUESS=mips-dec-ultrix$UNAME_RELEASE ;; VAX*:ULTRIX*:*:*) GUESS=vax-dec-ultrix$UNAME_RELEASE ;; 2020:CLIX:*:* | 2430:CLIX:*:*) GUESS=clipper-intergraph-clix$UNAME_RELEASE ;; mips:*:*:UMIPS | mips:*:*:RISCos) set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD -o "$dummy" "$dummy.c" && dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` && SYSTEM_NAME=`"$dummy" "$dummyarg"` && { echo "$SYSTEM_NAME"; exit; } GUESS=mips-mips-riscos$UNAME_RELEASE ;; Motorola:PowerMAX_OS:*:*) GUESS=powerpc-motorola-powermax ;; Motorola:*:4.3:PL8-*) GUESS=powerpc-harris-powermax ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) GUESS=powerpc-harris-powermax ;; Night_Hawk:Power_UNIX:*:*) GUESS=powerpc-harris-powerunix ;; m88k:CX/UX:7*:*) GUESS=m88k-harris-cxux7 ;; m88k:*:4*:R4*) GUESS=m88k-motorola-sysv4 ;; m88k:*:3*:R3*) GUESS=m88k-motorola-sysv3 ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if test "$UNAME_PROCESSOR" = mc88100 || test "$UNAME_PROCESSOR" = mc88110 then if test "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx || \ test "$TARGET_BINARY_INTERFACE"x = x then GUESS=m88k-dg-dgux$UNAME_RELEASE else GUESS=m88k-dg-dguxbcs$UNAME_RELEASE fi else GUESS=i586-dg-dgux$UNAME_RELEASE fi ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) GUESS=m88k-dolphin-sysv3 ;; M88*:*:R3*:*) # Delta 88k system running SVR3 GUESS=m88k-motorola-sysv3 ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) GUESS=m88k-tektronix-sysv3 ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) GUESS=m68k-tektronix-bsd ;; *:IRIX*:*:*) IRIX_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/g'` GUESS=mips-sgi-irix$IRIX_REL ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. GUESS=romp-ibm-aix # uname -m gives an 8 hex-code CPU id ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) GUESS=i386-ibm-aix ;; ia64:AIX:*:*) if test -x /usr/bin/oslevel ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=$UNAME_VERSION.$UNAME_RELEASE fi GUESS=$UNAME_MACHINE-ibm-aix$IBM_REV ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #include main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` then GUESS=$SYSTEM_NAME else GUESS=rs6000-ibm-aix3.2.5 fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then GUESS=rs6000-ibm-aix3.2.4 else GUESS=rs6000-ibm-aix3.2 fi ;; *:AIX:*:[4567]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if test -x /usr/bin/lslpp ; then IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | \ awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` else IBM_REV=$UNAME_VERSION.$UNAME_RELEASE fi GUESS=$IBM_ARCH-ibm-aix$IBM_REV ;; *:AIX:*:*) GUESS=rs6000-ibm-aix ;; ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*) GUESS=romp-ibm-bsd4.4 ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and GUESS=romp-ibm-bsd$UNAME_RELEASE # 4.3 with uname added to ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) GUESS=rs6000-bull-bosx ;; DPX/2?00:B.O.S.:*:*) GUESS=m68k-bull-sysv3 ;; 9000/[34]??:4.3bsd:1.*:*) GUESS=m68k-hp-bsd ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) GUESS=m68k-hp-bsd4.4 ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'` case $UNAME_MACHINE in 9000/31?) HP_ARCH=m68000 ;; 9000/[34]??) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if test -x /usr/bin/getconf; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case $sc_cpu_version in 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case $sc_kernel_bits in 32) HP_ARCH=hppa2.0n ;; 64) HP_ARCH=hppa2.0w ;; '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20 esac ;; esac fi if test "$HP_ARCH" = ""; then set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #define _HPUX_SOURCE #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac if test "$HP_ARCH" = hppa2.0w then set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler # generating 64-bit code. GNU and HP use different nomenclature: # # $ CC_FOR_BUILD=cc ./config.guess # => hppa2.0w-hp-hpux11.23 # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | grep -q __LP64__ then HP_ARCH=hppa2.0w else HP_ARCH=hppa64 fi fi GUESS=$HP_ARCH-hp-hpux$HPUX_REV ;; ia64:HP-UX:*:*) HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'` GUESS=ia64-hp-hpux$HPUX_REV ;; 3050*:HI-UX:*:*) set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` && { echo "$SYSTEM_NAME"; exit; } GUESS=unknown-hitachi-hiuxwe2 ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*) GUESS=hppa1.1-hp-bsd ;; 9000/8??:4.3bsd:*:*) GUESS=hppa1.0-hp-bsd ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) GUESS=hppa1.0-hp-mpeix ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*) GUESS=hppa1.1-hp-osf ;; hp8??:OSF1:*:*) GUESS=hppa1.0-hp-osf ;; i*86:OSF1:*:*) if test -x /usr/sbin/sysversion ; then GUESS=$UNAME_MACHINE-unknown-osf1mk else GUESS=$UNAME_MACHINE-unknown-osf1 fi ;; parisc*:Lites*:*:*) GUESS=hppa1.1-hp-lites ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) GUESS=c1-convex-bsd ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) GUESS=c34-convex-bsd ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) GUESS=c38-convex-bsd ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) GUESS=c4-convex-bsd ;; CRAY*Y-MP:*:*:*) CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` GUESS=ymp-cray-unicos$CRAY_REL ;; CRAY*[A-Z]90:*:*:*) echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` GUESS=t90-cray-unicos$CRAY_REL ;; CRAY*T3E:*:*:*) CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` GUESS=alphaev5-cray-unicosmk$CRAY_REL ;; CRAY*SV1:*:*:*) CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` GUESS=sv1-cray-unicos$CRAY_REL ;; *:UNICOS/mp:*:*) CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` GUESS=craynv-cray-unicosmp$CRAY_REL ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'` GUESS=${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL} ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` GUESS=sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL} ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) GUESS=$UNAME_MACHINE-pc-bsdi$UNAME_RELEASE ;; sparc*:BSD/OS:*:*) GUESS=sparc-unknown-bsdi$UNAME_RELEASE ;; *:BSD/OS:*:*) GUESS=$UNAME_MACHINE-unknown-bsdi$UNAME_RELEASE ;; arm:FreeBSD:*:*) UNAME_PROCESSOR=`uname -p` set_cc_for_build if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabi else FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabihf fi ;; *:FreeBSD:*:*) UNAME_PROCESSOR=`/usr/bin/uname -p` case $UNAME_PROCESSOR in amd64) UNAME_PROCESSOR=x86_64 ;; i386) UNAME_PROCESSOR=i586 ;; esac FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL ;; i*:CYGWIN*:*) GUESS=$UNAME_MACHINE-pc-cygwin ;; *:MINGW64*:*) GUESS=$UNAME_MACHINE-pc-mingw64 ;; *:MINGW*:*) GUESS=$UNAME_MACHINE-pc-mingw32 ;; *:MSYS*:*) GUESS=$UNAME_MACHINE-pc-msys ;; i*:PW*:*) GUESS=$UNAME_MACHINE-pc-pw32 ;; *:SerenityOS:*:*) GUESS=$UNAME_MACHINE-pc-serenity ;; *:Interix*:*) case $UNAME_MACHINE in x86) GUESS=i586-pc-interix$UNAME_RELEASE ;; authenticamd | genuineintel | EM64T) GUESS=x86_64-unknown-interix$UNAME_RELEASE ;; IA64) GUESS=ia64-unknown-interix$UNAME_RELEASE ;; esac ;; i*:UWIN*:*) GUESS=$UNAME_MACHINE-pc-uwin ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) GUESS=x86_64-pc-cygwin ;; prep*:SunOS:5.*:*) SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` GUESS=powerpcle-unknown-solaris2$SUN_REL ;; *:GNU:*:*) # the GNU system GNU_ARCH=`echo "$UNAME_MACHINE" | sed -e 's,[-/].*$,,'` GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's,/.*$,,'` GUESS=$GNU_ARCH-unknown-$LIBC$GNU_REL ;; *:GNU/*:*:*) # other systems with GNU libc and userland GNU_SYS=`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"` GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` GUESS=$UNAME_MACHINE-unknown-$GNU_SYS$GNU_REL-$LIBC ;; *:Minix:*:*) GUESS=$UNAME_MACHINE-unknown-minix ;; aarch64:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' /proc/cpuinfo 2>/dev/null` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep -q ld.so.1 if test "$?" = 0 ; then LIBC=gnulibc1 ; fi GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; arc:Linux:*:* | arceb:Linux:*:* | arc32:Linux:*:* | arc64:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; arm*:Linux:*:*) set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then GUESS=$UNAME_MACHINE-unknown-linux-$LIBC else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabi else GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabihf fi fi ;; avr32*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; cris:Linux:*:*) GUESS=$UNAME_MACHINE-axis-linux-$LIBC ;; crisv32:Linux:*:*) GUESS=$UNAME_MACHINE-axis-linux-$LIBC ;; e2k:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; frv:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; hexagon:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; i*86:Linux:*:*) GUESS=$UNAME_MACHINE-pc-linux-$LIBC ;; ia64:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; k1om:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; loongarch32:Linux:*:* | loongarch64:Linux:*:* | loongarchx32:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; m32r*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; m68*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; mips:Linux:*:* | mips64:Linux:*:*) set_cc_for_build IS_GLIBC=0 test x"${LIBC}" = xgnu && IS_GLIBC=1 sed 's/^ //' << EOF > "$dummy.c" #undef CPU #undef mips #undef mipsel #undef mips64 #undef mips64el #if ${IS_GLIBC} && defined(_ABI64) LIBCABI=gnuabi64 #else #if ${IS_GLIBC} && defined(_ABIN32) LIBCABI=gnuabin32 #else LIBCABI=${LIBC} #endif #endif #if ${IS_GLIBC} && defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 CPU=mipsisa64r6 #else #if ${IS_GLIBC} && !defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 CPU=mipsisa32r6 #else #if defined(__mips64) CPU=mips64 #else CPU=mips #endif #endif #endif #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) MIPS_ENDIAN=el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) MIPS_ENDIAN= #else MIPS_ENDIAN= #endif #endif EOF cc_set_vars=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI'` eval "$cc_set_vars" test "x$CPU" != x && { echo "$CPU${MIPS_ENDIAN}-unknown-linux-$LIBCABI"; exit; } ;; mips64el:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; openrisc*:Linux:*:*) GUESS=or1k-unknown-linux-$LIBC ;; or32:Linux:*:* | or1k*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; padre:Linux:*:*) GUESS=sparc-unknown-linux-$LIBC ;; parisc64:Linux:*:* | hppa64:Linux:*:*) GUESS=hppa64-unknown-linux-$LIBC ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) GUESS=hppa1.1-unknown-linux-$LIBC ;; PA8*) GUESS=hppa2.0-unknown-linux-$LIBC ;; *) GUESS=hppa-unknown-linux-$LIBC ;; esac ;; ppc64:Linux:*:*) GUESS=powerpc64-unknown-linux-$LIBC ;; ppc:Linux:*:*) GUESS=powerpc-unknown-linux-$LIBC ;; ppc64le:Linux:*:*) GUESS=powerpc64le-unknown-linux-$LIBC ;; ppcle:Linux:*:*) GUESS=powerpcle-unknown-linux-$LIBC ;; riscv32:Linux:*:* | riscv32be:Linux:*:* | riscv64:Linux:*:* | riscv64be:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; s390:Linux:*:* | s390x:Linux:*:*) GUESS=$UNAME_MACHINE-ibm-linux-$LIBC ;; sh64*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; sh*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; sparc:Linux:*:* | sparc64:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; tile*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; vax:Linux:*:*) GUESS=$UNAME_MACHINE-dec-linux-$LIBC ;; x86_64:Linux:*:*) set_cc_for_build LIBCABI=$LIBC if test "$CC_FOR_BUILD" != no_compiler_found; then if (echo '#ifdef __ILP32__'; echo IS_X32; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_X32 >/dev/null then LIBCABI=${LIBC}x32 fi fi GUESS=$UNAME_MACHINE-pc-linux-$LIBCABI ;; xtensa*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. GUESS=i386-sequent-sysv4 ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. GUESS=$UNAME_MACHINE-pc-sysv4.2uw$UNAME_VERSION ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. GUESS=$UNAME_MACHINE-pc-os2-emx ;; i*86:XTS-300:*:STOP) GUESS=$UNAME_MACHINE-unknown-stop ;; i*86:atheos:*:*) GUESS=$UNAME_MACHINE-unknown-atheos ;; i*86:syllable:*:*) GUESS=$UNAME_MACHINE-pc-syllable ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) GUESS=i386-unknown-lynxos$UNAME_RELEASE ;; i*86:*DOS:*:*) GUESS=$UNAME_MACHINE-pc-msdosdjgpp ;; i*86:*:4.*:*) UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then GUESS=$UNAME_MACHINE-univel-sysv$UNAME_REL else GUESS=$UNAME_MACHINE-pc-sysv$UNAME_REL fi ;; i*86:*:5:[678]*) # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac GUESS=$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 GUESS=$UNAME_MACHINE-pc-sco$UNAME_REL else GUESS=$UNAME_MACHINE-pc-sysv32 fi ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i586. # Note: whatever this is, it MUST be the same as what config.sub # prints for the "djgpp" host, or else GDB configure will decide that # this is a cross-build. GUESS=i586-pc-msdosdjgpp ;; Intel:Mach:3*:*) GUESS=i386-pc-mach3 ;; paragon:*:*:*) GUESS=i860-intel-osf1 ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then GUESS=i860-stardent-sysv$UNAME_RELEASE # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. GUESS=i860-unknown-sysv$UNAME_RELEASE # Unknown i860-SVR4 fi ;; mini*:CTIX:SYS*5:*) # "miniframe" GUESS=m68010-convergent-sysv ;; mc68k:UNIX:SYSTEM5:3.51m) GUESS=m68k-convergent-sysv ;; M680?0:D-NIX:5.3:*) GUESS=m68k-diab-dnix ;; M68*:*:R3V[5678]*:*) test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; NCR*:*:4.2:* | MPRAS*:*:4.2:*) OS_REL='.3' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) GUESS=m68k-unknown-lynxos$UNAME_RELEASE ;; mc68030:UNIX_System_V:4.*:*) GUESS=m68k-atari-sysv4 ;; TSUNAMI:LynxOS:2.*:*) GUESS=sparc-unknown-lynxos$UNAME_RELEASE ;; rs6000:LynxOS:2.*:*) GUESS=rs6000-unknown-lynxos$UNAME_RELEASE ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) GUESS=powerpc-unknown-lynxos$UNAME_RELEASE ;; SM[BE]S:UNIX_SV:*:*) GUESS=mips-dde-sysv$UNAME_RELEASE ;; RM*:ReliantUNIX-*:*:*) GUESS=mips-sni-sysv4 ;; RM*:SINIX-*:*:*) GUESS=mips-sni-sysv4 ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` GUESS=$UNAME_MACHINE-sni-sysv4 else GUESS=ns32k-sni-sysv fi ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says GUESS=i586-unisys-sysv4 ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm GUESS=hppa1.1-stratus-sysv4 ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. GUESS=i860-stratus-sysv4 ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. GUESS=$UNAME_MACHINE-stratus-vos ;; *:VOS:*:*) # From Paul.Green@stratus.com. GUESS=hppa1.1-stratus-vos ;; mc68*:A/UX:*:*) GUESS=m68k-apple-aux$UNAME_RELEASE ;; news*:NEWS-OS:6*:*) GUESS=mips-sony-newsos6 ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if test -d /usr/nec; then GUESS=mips-nec-sysv$UNAME_RELEASE else GUESS=mips-unknown-sysv$UNAME_RELEASE fi ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. GUESS=powerpc-be-beos ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. GUESS=powerpc-apple-beos ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. GUESS=i586-pc-beos ;; BePC:Haiku:*:*) # Haiku running on Intel PC compatible. GUESS=i586-pc-haiku ;; x86_64:Haiku:*:*) GUESS=x86_64-unknown-haiku ;; SX-4:SUPER-UX:*:*) GUESS=sx4-nec-superux$UNAME_RELEASE ;; SX-5:SUPER-UX:*:*) GUESS=sx5-nec-superux$UNAME_RELEASE ;; SX-6:SUPER-UX:*:*) GUESS=sx6-nec-superux$UNAME_RELEASE ;; SX-7:SUPER-UX:*:*) GUESS=sx7-nec-superux$UNAME_RELEASE ;; SX-8:SUPER-UX:*:*) GUESS=sx8-nec-superux$UNAME_RELEASE ;; SX-8R:SUPER-UX:*:*) GUESS=sx8r-nec-superux$UNAME_RELEASE ;; SX-ACE:SUPER-UX:*:*) GUESS=sxace-nec-superux$UNAME_RELEASE ;; Power*:Rhapsody:*:*) GUESS=powerpc-apple-rhapsody$UNAME_RELEASE ;; *:Rhapsody:*:*) GUESS=$UNAME_MACHINE-apple-rhapsody$UNAME_RELEASE ;; arm64:Darwin:*:*) GUESS=aarch64-apple-darwin$UNAME_RELEASE ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` case $UNAME_PROCESSOR in unknown) UNAME_PROCESSOR=powerpc ;; esac if command -v xcode-select > /dev/null 2> /dev/null && \ ! xcode-select --print-path > /dev/null 2> /dev/null ; then # Avoid executing cc if there is no toolchain installed as # cc will be a stub that puts up a graphical alert # prompting the user to install developer tools. CC_FOR_BUILD=no_compiler_found else set_cc_for_build fi if test "$CC_FOR_BUILD" != no_compiler_found; then if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then case $UNAME_PROCESSOR in i386) UNAME_PROCESSOR=x86_64 ;; powerpc) UNAME_PROCESSOR=powerpc64 ;; esac fi # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_PPC >/dev/null then UNAME_PROCESSOR=powerpc fi elif test "$UNAME_PROCESSOR" = i386 ; then # uname -m returns i386 or x86_64 UNAME_PROCESSOR=$UNAME_MACHINE fi GUESS=$UNAME_PROCESSOR-apple-darwin$UNAME_RELEASE ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = x86; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi GUESS=$UNAME_PROCESSOR-$UNAME_MACHINE-nto-qnx$UNAME_RELEASE ;; *:QNX:*:4*) GUESS=i386-pc-qnx ;; NEO-*:NONSTOP_KERNEL:*:*) GUESS=neo-tandem-nsk$UNAME_RELEASE ;; NSE-*:NONSTOP_KERNEL:*:*) GUESS=nse-tandem-nsk$UNAME_RELEASE ;; NSR-*:NONSTOP_KERNEL:*:*) GUESS=nsr-tandem-nsk$UNAME_RELEASE ;; NSV-*:NONSTOP_KERNEL:*:*) GUESS=nsv-tandem-nsk$UNAME_RELEASE ;; NSX-*:NONSTOP_KERNEL:*:*) GUESS=nsx-tandem-nsk$UNAME_RELEASE ;; *:NonStop-UX:*:*) GUESS=mips-compaq-nonstopux ;; BS2000:POSIX*:*:*) GUESS=bs2000-siemens-sysv ;; DS/*:UNIX_System_V:*:*) GUESS=$UNAME_MACHINE-$UNAME_SYSTEM-$UNAME_RELEASE ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. if test "${cputype-}" = 386; then UNAME_MACHINE=i386 elif test "x${cputype-}" != x; then UNAME_MACHINE=$cputype fi GUESS=$UNAME_MACHINE-unknown-plan9 ;; *:TOPS-10:*:*) GUESS=pdp10-unknown-tops10 ;; *:TENEX:*:*) GUESS=pdp10-unknown-tenex ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) GUESS=pdp10-dec-tops20 ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) GUESS=pdp10-xkl-tops20 ;; *:TOPS-20:*:*) GUESS=pdp10-unknown-tops20 ;; *:ITS:*:*) GUESS=pdp10-unknown-its ;; SEI:*:*:SEIUX) GUESS=mips-sei-seiux$UNAME_RELEASE ;; *:DragonFly:*:*) DRAGONFLY_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` GUESS=$UNAME_MACHINE-unknown-dragonfly$DRAGONFLY_REL ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` case $UNAME_MACHINE in A*) GUESS=alpha-dec-vms ;; I*) GUESS=ia64-dec-vms ;; V*) GUESS=vax-dec-vms ;; esac ;; *:XENIX:*:SysV) GUESS=i386-pc-xenix ;; i*86:skyos:*:*) SKYOS_REL=`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'` GUESS=$UNAME_MACHINE-pc-skyos$SKYOS_REL ;; i*86:rdos:*:*) GUESS=$UNAME_MACHINE-pc-rdos ;; i*86:Fiwix:*:*) GUESS=$UNAME_MACHINE-pc-fiwix ;; *:AROS:*:*) GUESS=$UNAME_MACHINE-unknown-aros ;; x86_64:VMkernel:*:*) GUESS=$UNAME_MACHINE-unknown-esx ;; amd64:Isilon\ OneFS:*:*) GUESS=x86_64-unknown-onefs ;; *:Unleashed:*:*) GUESS=$UNAME_MACHINE-unknown-unleashed$UNAME_RELEASE ;; esac # Do we have a guess based on uname results? if test "x$GUESS" != x; then echo "$GUESS" exit fi # No uname command or uname output not recognized. set_cc_for_build cat > "$dummy.c" < #include #endif #if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) #if defined (vax) || defined (__vax) || defined (__vax__) || defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) #include #if defined(_SIZE_T_) || defined(SIGLOST) #include #endif #endif #endif main () { #if defined (sony) #if defined (MIPSEB) /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, I don't know.... */ printf ("mips-sony-bsd\n"); exit (0); #else #include printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 "4" #else "" #endif ); exit (0); #endif #endif #if defined (NeXT) #if !defined (__ARCHITECTURE__) #define __ARCHITECTURE__ "m68k" #endif int version; version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; if (version < 4) printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); else printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); exit (0); #endif #if defined (MULTIMAX) || defined (n16) #if defined (UMAXV) printf ("ns32k-encore-sysv\n"); exit (0); #else #if defined (CMU) printf ("ns32k-encore-mach\n"); exit (0); #else printf ("ns32k-encore-bsd\n"); exit (0); #endif #endif #endif #if defined (__386BSD__) printf ("i386-pc-bsd\n"); exit (0); #endif #if defined (sequent) #if defined (i386) printf ("i386-sequent-dynix\n"); exit (0); #endif #if defined (ns32000) printf ("ns32k-sequent-dynix\n"); exit (0); #endif #endif #if defined (_SEQUENT_) struct utsname un; uname(&un); if (strncmp(un.version, "V2", 2) == 0) { printf ("i386-sequent-ptx2\n"); exit (0); } if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ printf ("i386-sequent-ptx1\n"); exit (0); } printf ("i386-sequent-ptx\n"); exit (0); #endif #if defined (vax) #if !defined (ultrix) #include #if defined (BSD) #if BSD == 43 printf ("vax-dec-bsd4.3\n"); exit (0); #else #if BSD == 199006 printf ("vax-dec-bsd4.3reno\n"); exit (0); #else printf ("vax-dec-bsd\n"); exit (0); #endif #endif #else printf ("vax-dec-bsd\n"); exit (0); #endif #else #if defined(_SIZE_T_) || defined(SIGLOST) struct utsname un; uname (&un); printf ("vax-dec-ultrix%s\n", un.release); exit (0); #else printf ("vax-dec-ultrix\n"); exit (0); #endif #endif #endif #if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) #if defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) #if defined(_SIZE_T_) || defined(SIGLOST) struct utsname *un; uname (&un); printf ("mips-dec-ultrix%s\n", un.release); exit (0); #else printf ("mips-dec-ultrix\n"); exit (0); #endif #endif #endif #if defined (alliant) && defined (i860) printf ("i860-alliant-bsd\n"); exit (0); #endif exit (1); } EOF $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=`"$dummy"` && { echo "$SYSTEM_NAME"; exit; } # Apollos put the system type in the environment. test -d /usr/apollo && { echo "$ISP-apollo-$SYSTYPE"; exit; } echo "$0: unable to guess system type" >&2 case $UNAME_MACHINE:$UNAME_SYSTEM in mips:Linux | mips64:Linux) # If we got here on MIPS GNU/Linux, output extra information. cat >&2 <&2 <&2 </dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` /bin/uname -X = `(/bin/uname -X) 2>/dev/null` hostinfo = `(hostinfo) 2>/dev/null` /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = "$UNAME_MACHINE" UNAME_RELEASE = "$UNAME_RELEASE" UNAME_SYSTEM = "$UNAME_SYSTEM" UNAME_VERSION = "$UNAME_VERSION" EOF fi exit 1 # Local variables: # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: geany-2.0/build-aux/install-sh0000754000175000017500000003577614514252334013321 00000000000000#!/bin/sh # install - install a program, script, or datafile scriptversion=2020-11-14.01; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the # following copyright and license. # # Copyright (C) 1994 X Consortium # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name of the X Consortium shall not # be used in advertising or otherwise to promote the sale, use or other deal- # ings in this Software without prior written authorization from the X Consor- # tium. # # # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent # 'make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. tab=' ' nl=' ' IFS=" $tab$nl" # Set DOITPROG to "echo" to test this script. doit=${DOITPROG-} doit_exec=${doit:-exec} # Put in absolute file names if you don't have them in your path; # or use environment vars. chgrpprog=${CHGRPPROG-chgrp} chmodprog=${CHMODPROG-chmod} chownprog=${CHOWNPROG-chown} cmpprog=${CMPPROG-cmp} cpprog=${CPPROG-cp} mkdirprog=${MKDIRPROG-mkdir} mvprog=${MVPROG-mv} rmprog=${RMPROG-rm} stripprog=${STRIPPROG-strip} posix_mkdir= # Desired mode of installed file. mode=0755 # Create dirs (including intermediate dirs) using mode 755. # This is like GNU 'install' as of coreutils 8.32 (2020). mkdir_umask=22 backupsuffix= chgrpcmd= chmodcmd=$chmodprog chowncmd= mvcmd=$mvprog rmcmd="$rmprog -f" stripcmd= src= dst= dir_arg= dst_arg= copy_on_change=false is_target_a_directory=possibly usage="\ Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE or: $0 [OPTION]... SRCFILES... DIRECTORY or: $0 [OPTION]... -t DIRECTORY SRCFILES... or: $0 [OPTION]... -d DIRECTORIES... In the 1st form, copy SRCFILE to DSTFILE. In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. In the 4th, create DIRECTORIES. Options: --help display this help and exit. --version display version info and exit. -c (ignored) -C install only if different (preserve data modification time) -d create directories instead of installing files. -g GROUP $chgrpprog installed files to GROUP. -m MODE $chmodprog installed files to MODE. -o USER $chownprog installed files to USER. -p pass -p to $cpprog. -s $stripprog installed files. -S SUFFIX attempt to back up existing files, with suffix SUFFIX. -t DIRECTORY install into DIRECTORY. -T report an error if DSTFILE is a directory. Environment variables override the default commands: CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG By default, rm is invoked with -f; when overridden with RMPROG, it's up to you to specify -f if you want it. If -S is not specified, no backups are attempted. Email bug reports to bug-automake@gnu.org. Automake home page: https://www.gnu.org/software/automake/ " while test $# -ne 0; do case $1 in -c) ;; -C) copy_on_change=true;; -d) dir_arg=true;; -g) chgrpcmd="$chgrpprog $2" shift;; --help) echo "$usage"; exit $?;; -m) mode=$2 case $mode in *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) echo "$0: invalid mode: $mode" >&2 exit 1;; esac shift;; -o) chowncmd="$chownprog $2" shift;; -p) cpprog="$cpprog -p";; -s) stripcmd=$stripprog;; -S) backupsuffix="$2" shift;; -t) is_target_a_directory=always dst_arg=$2 # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac shift;; -T) is_target_a_directory=never;; --version) echo "$0 $scriptversion"; exit $?;; --) shift break;; -*) echo "$0: invalid option: $1" >&2 exit 1;; *) break;; esac shift done # We allow the use of options -d and -T together, by making -d # take the precedence; this is for compatibility with GNU install. if test -n "$dir_arg"; then if test -n "$dst_arg"; then echo "$0: target directory not allowed when installing a directory." >&2 exit 1 fi fi if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then # When -d is used, all remaining arguments are directories to create. # When -t is used, the destination is already specified. # Otherwise, the last argument is the destination. Remove it from $@. for arg do if test -n "$dst_arg"; then # $@ is not empty: it contains at least $arg. set fnord "$@" "$dst_arg" shift # fnord fi shift # arg dst_arg=$arg # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac done fi if test $# -eq 0; then if test -z "$dir_arg"; then echo "$0: no input file specified." >&2 exit 1 fi # It's OK to call 'install-sh -d' without argument. # This can happen when creating conditional directories. exit 0 fi if test -z "$dir_arg"; then if test $# -gt 1 || test "$is_target_a_directory" = always; then if test ! -d "$dst_arg"; then echo "$0: $dst_arg: Is not a directory." >&2 exit 1 fi fi fi if test -z "$dir_arg"; then do_exit='(exit $ret); exit $ret' trap "ret=129; $do_exit" 1 trap "ret=130; $do_exit" 2 trap "ret=141; $do_exit" 13 trap "ret=143; $do_exit" 15 # Set umask so as not to create temps with too-generous modes. # However, 'strip' requires both read and write access to temps. case $mode in # Optimize common cases. *644) cp_umask=133;; *755) cp_umask=22;; *[0-7]) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw='% 200' fi cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; *) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw=,u+rw fi cp_umask=$mode$u_plus_rw;; esac fi for src do # Protect names problematic for 'test' and other utilities. case $src in -* | [=\(\)!]) src=./$src;; esac if test -n "$dir_arg"; then dst=$src dstdir=$dst test -d "$dstdir" dstdir_status=$? # Don't chown directories that already exist. if test $dstdir_status = 0; then chowncmd="" fi else # Waiting for this to be detected by the "$cpprog $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if test ! -f "$src" && test ! -d "$src"; then echo "$0: $src does not exist." >&2 exit 1 fi if test -z "$dst_arg"; then echo "$0: no destination specified." >&2 exit 1 fi dst=$dst_arg # If destination is a directory, append the input filename. if test -d "$dst"; then if test "$is_target_a_directory" = never; then echo "$0: $dst_arg: Is a directory" >&2 exit 1 fi dstdir=$dst dstbase=`basename "$src"` case $dst in */) dst=$dst$dstbase;; *) dst=$dst/$dstbase;; esac dstdir_status=0 else dstdir=`dirname "$dst"` test -d "$dstdir" dstdir_status=$? fi fi case $dstdir in */) dstdirslash=$dstdir;; *) dstdirslash=$dstdir/;; esac obsolete_mkdir_used=false if test $dstdir_status != 0; then case $posix_mkdir in '') # With -d, create the new directory with the user-specified mode. # Otherwise, rely on $mkdir_umask. if test -n "$dir_arg"; then mkdir_mode=-m$mode else mkdir_mode= fi posix_mkdir=false # The $RANDOM variable is not portable (e.g., dash). Use it # here however when possible just to lower collision chance. tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ trap ' ret=$? rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null exit $ret ' 0 # Because "mkdir -p" follows existing symlinks and we likely work # directly in world-writeable /tmp, make sure that the '$tmpdir' # directory is successfully created first before we actually test # 'mkdir -p'. if (umask $mkdir_umask && $mkdirprog $mkdir_mode "$tmpdir" && exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 then if test -z "$dir_arg" || { # Check for POSIX incompatibilities with -m. # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or # other-writable bit of parent directory when it shouldn't. # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. test_tmpdir="$tmpdir/a" ls_ld_tmpdir=`ls -ld "$test_tmpdir"` case $ls_ld_tmpdir in d????-?r-*) different_mode=700;; d????-?--*) different_mode=755;; *) false;; esac && $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" } } then posix_mkdir=: fi rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" else # Remove any dirs left behind by ancient mkdir implementations. rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null fi trap '' 0;; esac if $posix_mkdir && ( umask $mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" ) then : else # mkdir does not conform to POSIX, # or it failed possibly due to a race condition. Create the # directory the slow way, step by step, checking for races as we go. case $dstdir in /*) prefix='/';; [-=\(\)!]*) prefix='./';; *) prefix='';; esac oIFS=$IFS IFS=/ set -f set fnord $dstdir shift set +f IFS=$oIFS prefixes= for d do test X"$d" = X && continue prefix=$prefix$d if test -d "$prefix"; then prefixes= else if $posix_mkdir; then (umask $mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break # Don't fail if two instances are running concurrently. test -d "$prefix" || exit 1 else case $prefix in *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; *) qprefix=$prefix;; esac prefixes="$prefixes '$qprefix'" fi fi prefix=$prefix/ done if test -n "$prefixes"; then # Don't fail if two instances are running concurrently. (umask $mkdir_umask && eval "\$doit_exec \$mkdirprog $prefixes") || test -d "$dstdir" || exit 1 obsolete_mkdir_used=true fi fi fi if test -n "$dir_arg"; then { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 else # Make a couple of temp file names in the proper directory. dsttmp=${dstdirslash}_inst.$$_ rmtmp=${dstdirslash}_rm.$$_ # Trap to clean up those temp files at exit. trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 # Copy the file name to the temp name. (umask $cp_umask && { test -z "$stripcmd" || { # Create $dsttmp read-write so that cp doesn't create it read-only, # which would cause strip to fail. if test -z "$doit"; then : >"$dsttmp" # No need to fork-exec 'touch'. else $doit touch "$dsttmp" fi } } && $doit_exec $cpprog "$src" "$dsttmp") && # and set any options; do chmod last to preserve setuid bits. # # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $cpprog $src $dsttmp" command. # { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && # If -C, don't bother to copy if it wouldn't change the file. if $copy_on_change && old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && set -f && set X $old && old=:$2:$4:$5:$6 && set X $new && new=:$2:$4:$5:$6 && set +f && test "$old" = "$new" && $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 then rm -f "$dsttmp" else # If $backupsuffix is set, and the file being installed # already exists, attempt a backup. Don't worry if it fails, # e.g., if mv doesn't support -f. if test -n "$backupsuffix" && test -f "$dst"; then $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null fi # Rename the file to the real destination. $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || # The rename failed, perhaps because mv can't rename something else # to itself, or perhaps because mv is so ancient that it does not # support -f. { # Now remove or move aside any old file at destination location. # We try this two ways since rm can't unlink itself on some # systems and the destination file might be busy for other # reasons. In this case, the final cleanup might fail but the new # file should still install successfully. { test ! -f "$dst" || $doit $rmcmd "$dst" 2>/dev/null || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && { $doit $rmcmd "$rmtmp" 2>/dev/null; :; } } || { echo "$0: cannot unlink or rename $dst" >&2 (exit 1); exit 1 } } && # Now rename the file to the real destination. $doit $mvcmd "$dsttmp" "$dst" } fi || exit 1 trap '' 0 fi done # Local variables: # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: geany-2.0/build-aux/ar-lib0000754000175000017500000001336314514252334012375 00000000000000#! /bin/sh # Wrapper for Microsoft lib.exe me=ar-lib scriptversion=2019-07-04.01; # UTC # Copyright (C) 2010-2021 Free Software Foundation, Inc. # Written by Peter Rosin . # # This program 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; either version 2, or (at your option) # any later version. # # This program 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 . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # This file is maintained in Automake, please report # bugs to or send patches to # . # func_error message func_error () { echo "$me: $1" 1>&2 exit 1 } file_conv= # func_file_conv build_file # Convert a $build file to $host form and store it in $file # Currently only supports Windows hosts. func_file_conv () { file=$1 case $file in / | /[!/]*) # absolute file, and not a UNC file if test -z "$file_conv"; then # lazily determine how to convert abs files case `uname -s` in MINGW*) file_conv=mingw ;; CYGWIN* | MSYS*) file_conv=cygwin ;; *) file_conv=wine ;; esac fi case $file_conv in mingw) file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` ;; cygwin | msys) file=`cygpath -m "$file" || echo "$file"` ;; wine) file=`winepath -w "$file" || echo "$file"` ;; esac ;; esac } # func_at_file at_file operation archive # Iterate over all members in AT_FILE performing OPERATION on ARCHIVE # for each of them. # When interpreting the content of the @FILE, do NOT use func_file_conv, # since the user would need to supply preconverted file names to # binutils ar, at least for MinGW. func_at_file () { operation=$2 archive=$3 at_file_contents=`cat "$1"` eval set x "$at_file_contents" shift for member do $AR -NOLOGO $operation:"$member" "$archive" || exit $? done } case $1 in '') func_error "no command. Try '$0 --help' for more information." ;; -h | --h*) cat <, 1996 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # # The first argument passed to this file is the canonical host specification, # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # The environment variables CC, GCC, LDFLAGS, LD, with_gnu_ld # should be set by the caller. # # The set of defined variables is at the end of this script. # Known limitations: # - On IRIX 6.5 with CC="cc", the run time search patch must not be longer # than 256 bytes, otherwise the compiler driver will dump core. The only # known workaround is to choose shorter directory names for the build # directory and/or the installation directory. # All known linkers require a '.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a shrext=.so host="$1" host_cpu=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` host_vendor=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` host_os=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` # Code taken from libtool.m4's _LT_CC_BASENAME. for cc_temp in $CC""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done cc_basename=`echo "$cc_temp" | sed -e 's%^.*/%%'` # Code taken from libtool.m4's _LT_COMPILER_PIC. wl= if test "$GCC" = yes; then wl='-Wl,' else case "$host_os" in aix*) wl='-Wl,' ;; mingw* | cygwin* | pw32* | os2* | cegcc*) ;; hpux9* | hpux10* | hpux11*) wl='-Wl,' ;; irix5* | irix6* | nonstopux*) wl='-Wl,' ;; linux* | k*bsd*-gnu | kopensolaris*-gnu) case $cc_basename in ecc*) wl='-Wl,' ;; icc* | ifort*) wl='-Wl,' ;; lf95*) wl='-Wl,' ;; nagfor*) wl='-Wl,-Wl,,' ;; pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) wl='-Wl,' ;; ccc*) wl='-Wl,' ;; xl* | bgxl* | bgf* | mpixl*) wl='-Wl,' ;; como) wl='-lopt=' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ F* | *Sun*Fortran*) wl= ;; *Sun\ C*) wl='-Wl,' ;; esac ;; esac ;; newsos6) ;; *nto* | *qnx*) ;; osf3* | osf4* | osf5*) wl='-Wl,' ;; rdos*) ;; solaris*) case $cc_basename in f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) wl='-Qoption ld ' ;; *) wl='-Wl,' ;; esac ;; sunos4*) wl='-Qoption ld ' ;; sysv4 | sysv4.2uw2* | sysv4.3*) wl='-Wl,' ;; sysv4*MP*) ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) wl='-Wl,' ;; unicos*) wl='-Wl,' ;; uts4*) ;; esac fi # Code taken from libtool.m4's _LT_LINKER_SHLIBS. hardcode_libdir_flag_spec= hardcode_libdir_separator= hardcode_direct=no hardcode_minus_L=no case "$host_os" in cygwin* | mingw* | pw32* | cegcc*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. if test "$GCC" != yes; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; openbsd*) with_gnu_ld=no ;; esac ld_shlibs=yes if test "$with_gnu_ld" = yes; then # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. # Unlike libtool, we use -rpath here, not --rpath, since the documented # option of GNU ld is called -rpath, not --rpath. hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' case "$host_os" in aix[3-9]*) # On AIX/PPC, the GNU linker is very broken if test "$host_cpu" != ia64; then ld_shlibs=no fi ;; amigaos*) case "$host_cpu" in powerpc) ;; m68k) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; esac ;; beos*) if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then : else ld_shlibs=no fi ;; cygwin* | mingw* | pw32* | cegcc*) # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. hardcode_libdir_flag_spec='-L$libdir' if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then : else ld_shlibs=no fi ;; haiku*) ;; interix[3-9]*) hardcode_direct=no hardcode_libdir_flag_spec='${wl}-rpath,$libdir' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then : else ld_shlibs=no fi ;; netbsd*) ;; solaris*) if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then ld_shlibs=no elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then : else ld_shlibs=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) ld_shlibs=no ;; *) if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`' else ld_shlibs=no fi ;; esac ;; sunos4*) hardcode_direct=yes ;; *) if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then : else ld_shlibs=no fi ;; esac if test "$ld_shlibs" = no; then hardcode_libdir_flag_spec= fi else case "$host_os" in aix3*) # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. hardcode_minus_L=yes if test "$GCC" = yes; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. hardcode_direct=unsupported fi ;; aix[4-9]*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no else aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) for ld_flag in $LDFLAGS; do if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then aix_use_runtimelinking=yes break fi done ;; esac fi hardcode_direct=yes hardcode_libdir_separator=':' if test "$GCC" = yes; then case $host_os in aix4.[012]|aix4.[012].*) collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && \ strings "$collect2name" | grep resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 hardcode_direct=unsupported hardcode_minus_L=yes hardcode_libdir_flag_spec='-L$libdir' hardcode_libdir_separator= fi ;; esac fi # Begin _LT_AC_SYS_LIBPATH_AIX. echo 'int main () { return 0; }' > conftest.c ${CC} ${LDFLAGS} conftest.c -o conftest aix_libpath=`dump -H conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } }'` if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } }'` fi if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib" fi rm -f conftest.c conftest # End _LT_AC_SYS_LIBPATH_AIX. if test "$aix_use_runtimelinking" = yes; then hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" else if test "$host_cpu" = ia64; then hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' else hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" fi fi ;; amigaos*) case "$host_cpu" in powerpc) ;; m68k) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; esac ;; bsdi[45]*) ;; cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. hardcode_libdir_flag_spec=' ' libext=lib ;; darwin* | rhapsody*) hardcode_direct=no if { case $cc_basename in ifort*) true;; *) test "$GCC" = yes;; esac; }; then : else ld_shlibs=no fi ;; dgux*) hardcode_libdir_flag_spec='-L$libdir' ;; freebsd2.[01]*) hardcode_direct=yes hardcode_minus_L=yes ;; freebsd* | dragonfly*) hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes ;; hpux9*) hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: hardcode_direct=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes ;; hpux10*) if test "$with_gnu_ld" = no; then hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: hardcode_direct=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes fi ;; hpux11*) if test "$with_gnu_ld" = no; then hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: case $host_cpu in hppa*64*|ia64*) hardcode_direct=no ;; *) hardcode_direct=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: ;; netbsd*) hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes ;; newsos6) hardcode_direct=yes hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: ;; *nto* | *qnx*) ;; openbsd*) if test -f /usr/libexec/ld.so; then hardcode_direct=yes if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then hardcode_libdir_flag_spec='${wl}-rpath,$libdir' else case "$host_os" in openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) hardcode_libdir_flag_spec='-R$libdir' ;; *) hardcode_libdir_flag_spec='${wl}-rpath,$libdir' ;; esac fi else ld_shlibs=no fi ;; os2*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; osf3*) hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: ;; osf4* | osf5*) if test "$GCC" = yes; then hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' else # Both cc and cxx compiler support -rpath directly hardcode_libdir_flag_spec='-rpath $libdir' fi hardcode_libdir_separator=: ;; solaris*) hardcode_libdir_flag_spec='-R$libdir' ;; sunos4*) hardcode_libdir_flag_spec='-L$libdir' hardcode_direct=yes hardcode_minus_L=yes ;; sysv4) case $host_vendor in sni) hardcode_direct=yes # is this really true??? ;; siemens) hardcode_direct=no ;; motorola) hardcode_direct=no #Motorola manual says yes, but my tests say they lie ;; esac ;; sysv4.3*) ;; sysv4*MP*) if test -d /usr/nec; then ld_shlibs=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) ;; sysv5* | sco3.2v5* | sco5v6*) hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' hardcode_libdir_separator=':' ;; uts4*) hardcode_libdir_flag_spec='-L$libdir' ;; *) ld_shlibs=no ;; esac fi # Check dynamic linker characteristics # Code taken from libtool.m4's _LT_SYS_DYNAMIC_LINKER. # Unlike libtool.m4, here we don't care about _all_ names of the library, but # only about the one the linker finds when passed -lNAME. This is the last # element of library_names_spec in libtool.m4, or possibly two of them if the # linker has special search rules. library_names_spec= # the last element of library_names_spec in libtool.m4 libname_spec='lib$name' case "$host_os" in aix3*) library_names_spec='$libname.a' ;; aix[4-9]*) library_names_spec='$libname$shrext' ;; amigaos*) case "$host_cpu" in powerpc*) library_names_spec='$libname$shrext' ;; m68k) library_names_spec='$libname.a' ;; esac ;; beos*) library_names_spec='$libname$shrext' ;; bsdi[45]*) library_names_spec='$libname$shrext' ;; cygwin* | mingw* | pw32* | cegcc*) shrext=.dll library_names_spec='$libname.dll.a $libname.lib' ;; darwin* | rhapsody*) shrext=.dylib library_names_spec='$libname$shrext' ;; dgux*) library_names_spec='$libname$shrext' ;; freebsd[23].*) library_names_spec='$libname$shrext$versuffix' ;; freebsd* | dragonfly*) library_names_spec='$libname$shrext' ;; gnu*) library_names_spec='$libname$shrext' ;; haiku*) library_names_spec='$libname$shrext' ;; hpux9* | hpux10* | hpux11*) case $host_cpu in ia64*) shrext=.so ;; hppa*64*) shrext=.sl ;; *) shrext=.sl ;; esac library_names_spec='$libname$shrext' ;; interix[3-9]*) library_names_spec='$libname$shrext' ;; irix5* | irix6* | nonstopux*) library_names_spec='$libname$shrext' case "$host_os" in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= ;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 ;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 ;; *) libsuff= shlibsuff= ;; esac ;; esac ;; linux*oldld* | linux*aout* | linux*coff*) ;; linux* | k*bsd*-gnu | kopensolaris*-gnu) library_names_spec='$libname$shrext' ;; knetbsd*-gnu) library_names_spec='$libname$shrext' ;; netbsd*) library_names_spec='$libname$shrext' ;; newsos6) library_names_spec='$libname$shrext' ;; *nto* | *qnx*) library_names_spec='$libname$shrext' ;; openbsd*) library_names_spec='$libname$shrext$versuffix' ;; os2*) libname_spec='$name' shrext=.dll library_names_spec='$libname.a' ;; osf3* | osf4* | osf5*) library_names_spec='$libname$shrext' ;; rdos*) ;; solaris*) library_names_spec='$libname$shrext' ;; sunos4*) library_names_spec='$libname$shrext$versuffix' ;; sysv4 | sysv4.3*) library_names_spec='$libname$shrext' ;; sysv4*MP*) library_names_spec='$libname$shrext' ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) library_names_spec='$libname$shrext' ;; tpf*) library_names_spec='$libname$shrext' ;; uts4*) library_names_spec='$libname$shrext' ;; esac sed_quote_subst='s/\(["`$\\]\)/\\\1/g' escaped_wl=`echo "X$wl" | sed -e 's/^X//' -e "$sed_quote_subst"` shlibext=`echo "$shrext" | sed -e 's,^\.,,'` escaped_libname_spec=`echo "X$libname_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` escaped_library_names_spec=`echo "X$library_names_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` escaped_hardcode_libdir_flag_spec=`echo "X$hardcode_libdir_flag_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` LC_ALL=C sed -e 's/^\([a-zA-Z0-9_]*\)=/acl_cv_\1=/' <. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Alexandre Oliva . case $1 in '') echo "$0: No command. Try '$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: depcomp [--help] [--version] PROGRAM [ARGS] Run PROGRAMS ARGS to compile a file, generating dependencies as side-effects. Environment variables: depmode Dependency tracking mode. source Source file read by 'PROGRAMS ARGS'. object Object file output by 'PROGRAMS ARGS'. DEPDIR directory where to store dependencies. depfile Dependency file to output. tmpdepfile Temporary file to use when outputting dependencies. libtool Whether libtool is used (yes/no). Report bugs to . EOF exit $? ;; -v | --v*) echo "depcomp $scriptversion" exit $? ;; esac # Get the directory component of the given path, and save it in the # global variables '$dir'. Note that this directory component will # be either empty or ending with a '/' character. This is deliberate. set_dir_from () { case $1 in */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;; *) dir=;; esac } # Get the suffix-stripped basename of the given path, and save it the # global variable '$base'. set_base_from () { base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'` } # If no dependency file was actually created by the compiler invocation, # we still have to create a dummy depfile, to avoid errors with the # Makefile "include basename.Plo" scheme. make_dummy_depfile () { echo "#dummy" > "$depfile" } # Factor out some common post-processing of the generated depfile. # Requires the auxiliary global variable '$tmpdepfile' to be set. aix_post_process_depfile () { # If the compiler actually managed to produce a dependency file, # post-process it. if test -f "$tmpdepfile"; then # Each line is of the form 'foo.o: dependency.h'. # Do two passes, one to just change these to # $object: dependency.h # and one to simply output # dependency.h: # which is needed to avoid the deleted-header problem. { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile" sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile" } > "$depfile" rm -f "$tmpdepfile" else make_dummy_depfile fi } # A tabulation character. tab=' ' # A newline character. nl=' ' # Character ranges might be problematic outside the C locale. # These definitions help. upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ lower=abcdefghijklmnopqrstuvwxyz digits=0123456789 alpha=${upper}${lower} if test -z "$depmode" || test -z "$source" || test -z "$object"; then echo "depcomp: Variables source, object and depmode must be set" 1>&2 exit 1 fi # Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. depfile=${depfile-`echo "$object" | sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} rm -f "$tmpdepfile" # Avoid interferences from the environment. gccflag= dashmflag= # Some modes work just like other modes, but use different flags. We # parameterize here, but still list the modes in the big case below, # to make depend.m4 easier to write. Note that we *cannot* use a case # here, because this file can only contain one case statement. if test "$depmode" = hp; then # HP compiler uses -M and no extra arg. gccflag=-M depmode=gcc fi if test "$depmode" = dashXmstdout; then # This is just like dashmstdout with a different argument. dashmflag=-xM depmode=dashmstdout fi cygpath_u="cygpath -u -f -" if test "$depmode" = msvcmsys; then # This is just like msvisualcpp but w/o cygpath translation. # Just convert the backslash-escaped backslashes to single forward # slashes to satisfy depend.m4 cygpath_u='sed s,\\\\,/,g' depmode=msvisualcpp fi if test "$depmode" = msvc7msys; then # This is just like msvc7 but w/o cygpath translation. # Just convert the backslash-escaped backslashes to single forward # slashes to satisfy depend.m4 cygpath_u='sed s,\\\\,/,g' depmode=msvc7 fi if test "$depmode" = xlc; then # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information. gccflag=-qmakedep=gcc,-MF depmode=gcc fi case "$depmode" in gcc3) ## gcc 3 implements dependency tracking that does exactly what ## we want. Yay! Note: for some reason libtool 1.4 doesn't like ## it if -MD -MP comes after the -MF stuff. Hmm. ## Unfortunately, FreeBSD c89 acceptance of flags depends upon ## the command line argument order; so add the flags where they ## appear in depend2.am. Note that the slowdown incurred here ## affects only configure: in makefiles, %FASTDEP% shortcuts this. for arg do case $arg in -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; *) set fnord "$@" "$arg" ;; esac shift # fnord shift # $arg done "$@" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi mv "$tmpdepfile" "$depfile" ;; gcc) ## Note that this doesn't just cater to obsosete pre-3.x GCC compilers. ## but also to in-use compilers like IMB xlc/xlC and the HP C compiler. ## (see the conditional assignment to $gccflag above). ## There are various ways to get dependency output from gcc. Here's ## why we pick this rather obscure method: ## - Don't want to use -MD because we'd like the dependencies to end ## up in a subdir. Having to rename by hand is ugly. ## (We might end up doing this anyway to support other compilers.) ## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like ## -MM, not -M (despite what the docs say). Also, it might not be ## supported by the other compilers which use the 'gcc' depmode. ## - Using -M directly means running the compiler twice (even worse ## than renaming). if test -z "$gccflag"; then gccflag=-MD, fi "$@" -Wp,"$gccflag$tmpdepfile" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" # The second -e expression handles DOS-style file names with drive # letters. sed -e 's/^[^:]*: / /' \ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" ## This next piece of magic avoids the "deleted header file" problem. ## The problem is that when a header file which appears in a .P file ## is deleted, the dependency causes make to die (because there is ## typically no way to rebuild the header). We avoid this by adding ## dummy dependencies for each header file. Too bad gcc doesn't do ## this for us directly. ## Some versions of gcc put a space before the ':'. On the theory ## that the space means something, we add a space to the output as ## well. hp depmode also adds that space, but also prefixes the VPATH ## to the object. Take care to not repeat it in the output. ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; sgi) if test "$libtool" = yes; then "$@" "-Wp,-MDupdate,$tmpdepfile" else "$@" -MDupdate "$tmpdepfile" fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files echo "$object : \\" > "$depfile" # Clip off the initial element (the dependent). Don't try to be # clever and replace this with sed code, as IRIX sed won't handle # lines with more than a fixed number of characters (4096 in # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; # the IRIX cc adds comments like '#:fec' to the end of the # dependency line. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \ | tr "$nl" ' ' >> "$depfile" echo >> "$depfile" # The second pass generates a dummy entry for each header file. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ >> "$depfile" else make_dummy_depfile fi rm -f "$tmpdepfile" ;; xlc) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; aix) # The C for AIX Compiler uses -M and outputs the dependencies # in a .u file. In older versions, this file always lives in the # current directory. Also, the AIX compiler puts '$object:' at the # start of each line; $object doesn't have directory information. # Version 6 uses the directory in both cases. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then tmpdepfile1=$dir$base.u tmpdepfile2=$base.u tmpdepfile3=$dir.libs/$base.u "$@" -Wc,-M else tmpdepfile1=$dir$base.u tmpdepfile2=$dir$base.u tmpdepfile3=$dir$base.u "$@" -M fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" do test -f "$tmpdepfile" && break done aix_post_process_depfile ;; tcc) # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26 # FIXME: That version still under development at the moment of writing. # Make that this statement remains true also for stable, released # versions. # It will wrap lines (doesn't matter whether long or short) with a # trailing '\', as in: # # foo.o : \ # foo.c \ # foo.h \ # # It will put a trailing '\' even on the last line, and will use leading # spaces rather than leading tabs (at least since its commit 0394caf7 # "Emit spaces for -MD"). "$@" -MD -MF "$tmpdepfile" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'. # We have to change lines of the first kind to '$object: \'. sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile" # And for each line of the second kind, we have to emit a 'dep.h:' # dummy dependency, to avoid the deleted-header problem. sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile" rm -f "$tmpdepfile" ;; ## The order of this option in the case statement is important, since the ## shell code in configure will try each of these formats in the order ## listed in this file. A plain '-MD' option would be understood by many ## compilers, so we must ensure this comes after the gcc and icc options. pgcc) # Portland's C compiler understands '-MD'. # Will always output deps to 'file.d' where file is the root name of the # source file under compilation, even if file resides in a subdirectory. # The object file name does not affect the name of the '.d' file. # pgcc 10.2 will output # foo.o: sub/foo.c sub/foo.h # and will wrap long lines using '\' : # foo.o: sub/foo.c ... \ # sub/foo.h ... \ # ... set_dir_from "$object" # Use the source, not the object, to determine the base name, since # that's sadly what pgcc will do too. set_base_from "$source" tmpdepfile=$base.d # For projects that build the same source file twice into different object # files, the pgcc approach of using the *source* file root name can cause # problems in parallel builds. Use a locking strategy to avoid stomping on # the same $tmpdepfile. lockdir=$base.d-lock trap " echo '$0: caught signal, cleaning up...' >&2 rmdir '$lockdir' exit 1 " 1 2 13 15 numtries=100 i=$numtries while test $i -gt 0; do # mkdir is a portable test-and-set. if mkdir "$lockdir" 2>/dev/null; then # This process acquired the lock. "$@" -MD stat=$? # Release the lock. rmdir "$lockdir" break else # If the lock is being held by a different process, wait # until the winning process is done or we timeout. while test -d "$lockdir" && test $i -gt 0; do sleep 1 i=`expr $i - 1` done fi i=`expr $i - 1` done trap - 1 2 13 15 if test $i -le 0; then echo "$0: failed to acquire lock after $numtries attempts" >&2 echo "$0: check lockdir '$lockdir'" >&2 exit 1 fi if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each line is of the form `foo.o: dependent.h', # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this invocation # correctly. Breaking it into two sed invocations is a workaround. sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp2) # The "hp" stanza above does not work with aCC (C++) and HP's ia64 # compilers, which have integrated preprocessors. The correct option # to use with these is +Maked; it writes dependencies to a file named # 'foo.d', which lands next to the object file, wherever that # happens to be. # Much of this is similar to the tru64 case; see comments there. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then tmpdepfile1=$dir$base.d tmpdepfile2=$dir.libs/$base.d "$@" -Wc,+Maked else tmpdepfile1=$dir$base.d tmpdepfile2=$dir$base.d "$@" +Maked fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" do test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile" # Add 'dependent.h:' lines. sed -ne '2,${ s/^ *// s/ \\*$// s/$/:/ p }' "$tmpdepfile" >> "$depfile" else make_dummy_depfile fi rm -f "$tmpdepfile" "$tmpdepfile2" ;; tru64) # The Tru64 compiler uses -MD to generate dependencies as a side # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'. # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put # dependencies in 'foo.d' instead, so we check for that too. # Subdirectories are respected. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then # Libtool generates 2 separate objects for the 2 libraries. These # two compilations output dependencies in $dir.libs/$base.o.d and # in $dir$base.o.d. We have to check for both files, because # one of the two compilations can be disabled. We should prefer # $dir$base.o.d over $dir.libs/$base.o.d because the latter is # automatically cleaned when .libs/ is deleted, while ignoring # the former would cause a distcleancheck panic. tmpdepfile1=$dir$base.o.d # libtool 1.5 tmpdepfile2=$dir.libs/$base.o.d # Likewise. tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504 "$@" -Wc,-MD else tmpdepfile1=$dir$base.d tmpdepfile2=$dir$base.d tmpdepfile3=$dir$base.d "$@" -MD fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" do test -f "$tmpdepfile" && break done # Same post-processing that is required for AIX mode. aix_post_process_depfile ;; msvc7) if test "$libtool" = yes; then showIncludes=-Wc,-showIncludes else showIncludes=-showIncludes fi "$@" $showIncludes > "$tmpdepfile" stat=$? grep -v '^Note: including file: ' "$tmpdepfile" if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" # The first sed program below extracts the file names and escapes # backslashes for cygpath. The second sed program outputs the file # name when reading, but also accumulates all include files in the # hold buffer in order to output them again at the end. This only # works with sed implementations that can handle large buffers. sed < "$tmpdepfile" -n ' /^Note: including file: *\(.*\)/ { s//\1/ s/\\/\\\\/g p }' | $cygpath_u | sort -u | sed -n ' s/ /\\ /g s/\(.*\)/'"$tab"'\1 \\/p s/.\(.*\) \\/\1:/ H $ { s/.*/'"$tab"'/ G p }' >> "$depfile" echo >> "$depfile" # make sure the fragment doesn't end with a backslash rm -f "$tmpdepfile" ;; msvc7msys) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; #nosideeffect) # This comment above is used by automake to tell side-effect # dependency tracking mechanisms from slower ones. dashmstdout) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout, regardless of -o. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # Remove '-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done test -z "$dashmflag" && dashmflag=-M # Require at least two characters before searching for ':' # in the target name. This is to cope with DOS-style filenames: # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise. "$@" $dashmflag | sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this sed invocation # correctly. Breaking it into two sed invocations is a workaround. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; dashXmstdout) # This case only exists to satisfy depend.m4. It is never actually # run, as this mode is specially recognized in the preamble. exit 1 ;; makedepend) "$@" || exit $? # Remove any Libtool call if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # X makedepend shift cleared=no eat=no for arg do case $cleared in no) set ""; shift cleared=yes ;; esac if test $eat = yes; then eat=no continue fi case "$arg" in -D*|-I*) set fnord "$@" "$arg"; shift ;; # Strip any option that makedepend may not understand. Remove # the object too, otherwise makedepend will parse it as a source file. -arch) eat=yes ;; -*|$object) ;; *) set fnord "$@" "$arg"; shift ;; esac done obj_suffix=`echo "$object" | sed 's/^.*\././'` touch "$tmpdepfile" ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" rm -f "$depfile" # makedepend may prepend the VPATH from the source file name to the object. # No need to regex-escape $object, excess matching of '.' is harmless. sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process the last invocation # correctly. Breaking it into two sed invocations is a workaround. sed '1,2d' "$tmpdepfile" \ | tr ' ' "$nl" \ | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" "$tmpdepfile".bak ;; cpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # Remove '-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done "$@" -E \ | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ | sed '$ s: \\$::' > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" cat < "$tmpdepfile" >> "$depfile" sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; msvisualcpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi IFS=" " for arg do case "$arg" in -o) shift ;; $object) shift ;; "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") set fnord "$@" shift shift ;; *) set fnord "$@" "$arg" shift shift ;; esac done "$@" -E 2>/dev/null | sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile" echo "$tab" >> "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" rm -f "$tmpdepfile" ;; msvcmsys) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; none) exec "$@" ;; *) echo "Unknown depmode $depmode" 1>&2 exit 1 ;; esac exit 0 # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: geany-2.0/build-aux/test-driver0000754000175000017500000001141714514252335013476 00000000000000#! /bin/sh # test-driver - basic testsuite driver script. scriptversion=2018-03-07.03; # UTC # Copyright (C) 2011-2021 Free Software Foundation, Inc. # # This program 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; either version 2, or (at your option) # any later version. # # This program 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 . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # This file is maintained in Automake, please report # bugs to or send patches to # . # Make unconditional expansion of undefined variables an error. This # helps a lot in preventing typo-related bugs. set -u usage_error () { echo "$0: $*" >&2 print_usage >&2 exit 2 } print_usage () { cat <"$log_file" "$@" >>"$log_file" 2>&1 estatus=$? if test $enable_hard_errors = no && test $estatus -eq 99; then tweaked_estatus=1 else tweaked_estatus=$estatus fi case $tweaked_estatus:$expect_failure in 0:yes) col=$red res=XPASS recheck=yes gcopy=yes;; 0:*) col=$grn res=PASS recheck=no gcopy=no;; 77:*) col=$blu res=SKIP recheck=no gcopy=yes;; 99:*) col=$mgn res=ERROR recheck=yes gcopy=yes;; *:yes) col=$lgn res=XFAIL recheck=no gcopy=yes;; *:*) col=$red res=FAIL recheck=yes gcopy=yes;; esac # Report the test outcome and exit status in the logs, so that one can # know whether the test passed or failed simply by looking at the '.log' # file, without the need of also peaking into the corresponding '.trs' # file (automake bug#11814). echo "$res $test_name (exit status: $estatus)" >>"$log_file" # Report outcome to console. echo "${col}${res}${std}: $test_name" # Register the test result, and other relevant metadata. echo ":test-result: $res" > $trs_file echo ":global-test-result: $res" >> $trs_file echo ":recheck: $recheck" >> $trs_file echo ":copy-in-global-log: $gcopy" >> $trs_file # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: geany-2.0/build-aux/ltmain.sh0000754000175000017500000121320114514252316013116 00000000000000#! /usr/bin/env sh ## DO NOT EDIT - This file generated from ./build-aux/ltmain.in ## by inline-source v2019-02-19.15 # libtool (GNU libtool) 2.4.7 # Provide generalized library-building support services. # Written by Gordon Matzigkeit , 1996 # Copyright (C) 1996-2019, 2021-2022 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # GNU Libtool 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; either version 2 of the License, or # (at your option) any later version. # # As a special exception to the GNU General Public License, # if you distribute this file as part of a program or library that # is built using GNU Libtool, you may include this file under the # same distribution terms that you use for the rest of that program. # # GNU Libtool 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 . PROGRAM=libtool PACKAGE=libtool VERSION="2.4.7 Debian-2.4.7-5" package_revision=2.4.7 ## ------ ## ## Usage. ## ## ------ ## # Run './libtool --help' for help with using this script from the # command line. ## ------------------------------- ## ## User overridable command paths. ## ## ------------------------------- ## # After configure completes, it has a better idea of some of the # shell tools we need than the defaults used by the functions shared # with bootstrap, so set those here where they can still be over- # ridden by the user, but otherwise take precedence. : ${AUTOCONF="autoconf"} : ${AUTOMAKE="automake"} ## -------------------------- ## ## Source external libraries. ## ## -------------------------- ## # Much of our low-level functionality needs to be sourced from external # libraries, which are installed to $pkgauxdir. # Set a version string for this script. scriptversion=2019-02-19.15; # UTC # General shell script boiler plate, and helper functions. # Written by Gary V. Vaughan, 2004 # This is free software. There is NO warranty; not even for # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # # Copyright (C) 2004-2019, 2021 Bootstrap Authors # # This file is dual licensed under the terms of the MIT license # , and GPL version 2 or later # . You must apply one of # these licenses when using or redistributing this software or any of # the files within it. See the URLs above, or the file `LICENSE` # included in the Bootstrap distribution for the full license texts. # Please report bugs or propose patches to: # ## ------ ## ## Usage. ## ## ------ ## # Evaluate this file near the top of your script to gain access to # the functions and variables defined here: # # . `echo "$0" | ${SED-sed} 's|[^/]*$||'`/build-aux/funclib.sh # # If you need to override any of the default environment variable # settings, do that before evaluating this file. ## -------------------- ## ## Shell normalisation. ## ## -------------------- ## # Some shells need a little help to be as Bourne compatible as possible. # Before doing anything else, make sure all that help has been provided! DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac fi # NLS nuisances: We save the old values in case they are required later. _G_user_locale= _G_safe_locale= for _G_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES do eval "if test set = \"\${$_G_var+set}\"; then save_$_G_var=\$$_G_var $_G_var=C export $_G_var _G_user_locale=\"$_G_var=\\\$save_\$_G_var; \$_G_user_locale\" _G_safe_locale=\"$_G_var=C; \$_G_safe_locale\" fi" done # These NLS vars are set unconditionally (bootstrap issue #24). Unset those # in case the environment reset is needed later and the $save_* variant is not # defined (see the code above). LC_ALL=C LANGUAGE=C export LANGUAGE LC_ALL # Make sure IFS has a sensible default sp=' ' nl=' ' IFS="$sp $nl" # There are apparently some retarded systems that use ';' as a PATH separator! if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # func_unset VAR # -------------- # Portably unset VAR. # In some shells, an 'unset VAR' statement leaves a non-zero return # status if VAR is already unset, which might be problematic if the # statement is used at the end of a function (thus poisoning its return # value) or when 'set -e' is active (causing even a spurious abort of # the script in this case). func_unset () { { eval $1=; (eval unset $1) >/dev/null 2>&1 && eval unset $1 || : ; } } # Make sure CDPATH doesn't cause `cd` commands to output the target dir. func_unset CDPATH # Make sure ${,E,F}GREP behave sanely. func_unset GREP_OPTIONS ## ------------------------- ## ## Locate command utilities. ## ## ------------------------- ## # func_executable_p FILE # ---------------------- # Check that FILE is an executable regular file. func_executable_p () { test -f "$1" && test -x "$1" } # func_path_progs PROGS_LIST CHECK_FUNC [PATH] # -------------------------------------------- # Search for either a program that responds to --version with output # containing "GNU", or else returned by CHECK_FUNC otherwise, by # trying all the directories in PATH with each of the elements of # PROGS_LIST. # # CHECK_FUNC should accept the path to a candidate program, and # set $func_check_prog_result if it truncates its output less than # $_G_path_prog_max characters. func_path_progs () { _G_progs_list=$1 _G_check_func=$2 _G_PATH=${3-"$PATH"} _G_path_prog_max=0 _G_path_prog_found=false _G_save_IFS=$IFS; IFS=${PATH_SEPARATOR-:} for _G_dir in $_G_PATH; do IFS=$_G_save_IFS test -z "$_G_dir" && _G_dir=. for _G_prog_name in $_G_progs_list; do for _exeext in '' .EXE; do _G_path_prog=$_G_dir/$_G_prog_name$_exeext func_executable_p "$_G_path_prog" || continue case `"$_G_path_prog" --version 2>&1` in *GNU*) func_path_progs_result=$_G_path_prog _G_path_prog_found=: ;; *) $_G_check_func $_G_path_prog func_path_progs_result=$func_check_prog_result ;; esac $_G_path_prog_found && break 3 done done done IFS=$_G_save_IFS test -z "$func_path_progs_result" && { echo "no acceptable sed could be found in \$PATH" >&2 exit 1 } } # We want to be able to use the functions in this file before configure # has figured out where the best binaries are kept, which means we have # to search for them ourselves - except when the results are already set # where we skip the searches. # Unless the user overrides by setting SED, search the path for either GNU # sed, or the sed that truncates its output the least. test -z "$SED" && { _G_sed_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ for _G_i in 1 2 3 4 5 6 7; do _G_sed_script=$_G_sed_script$nl$_G_sed_script done echo "$_G_sed_script" 2>/dev/null | sed 99q >conftest.sed _G_sed_script= func_check_prog_sed () { _G_path_prog=$1 _G_count=0 printf 0123456789 >conftest.in while : do cat conftest.in conftest.in >conftest.tmp mv conftest.tmp conftest.in cp conftest.in conftest.nl echo '' >> conftest.nl "$_G_path_prog" -f conftest.sed conftest.out 2>/dev/null || break diff conftest.out conftest.nl >/dev/null 2>&1 || break _G_count=`expr $_G_count + 1` if test "$_G_count" -gt "$_G_path_prog_max"; then # Best one so far, save it but keep looking for a better one func_check_prog_result=$_G_path_prog _G_path_prog_max=$_G_count fi # 10*(2^10) chars as input seems more than enough test 10 -lt "$_G_count" && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out } func_path_progs "sed gsed" func_check_prog_sed "$PATH:/usr/xpg4/bin" rm -f conftest.sed SED=$func_path_progs_result } # Unless the user overrides by setting GREP, search the path for either GNU # grep, or the grep that truncates its output the least. test -z "$GREP" && { func_check_prog_grep () { _G_path_prog=$1 _G_count=0 _G_path_prog_max=0 printf 0123456789 >conftest.in while : do cat conftest.in conftest.in >conftest.tmp mv conftest.tmp conftest.in cp conftest.in conftest.nl echo 'GREP' >> conftest.nl "$_G_path_prog" -e 'GREP$' -e '-(cannot match)-' conftest.out 2>/dev/null || break diff conftest.out conftest.nl >/dev/null 2>&1 || break _G_count=`expr $_G_count + 1` if test "$_G_count" -gt "$_G_path_prog_max"; then # Best one so far, save it but keep looking for a better one func_check_prog_result=$_G_path_prog _G_path_prog_max=$_G_count fi # 10*(2^10) chars as input seems more than enough test 10 -lt "$_G_count" && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out } func_path_progs "grep ggrep" func_check_prog_grep "$PATH:/usr/xpg4/bin" GREP=$func_path_progs_result } ## ------------------------------- ## ## User overridable command paths. ## ## ------------------------------- ## # All uppercase variable names are used for environment variables. These # variables can be overridden by the user before calling a script that # uses them if a suitable command of that name is not already available # in the command search PATH. : ${CP="cp -f"} : ${ECHO="printf %s\n"} : ${EGREP="$GREP -E"} : ${FGREP="$GREP -F"} : ${LN_S="ln -s"} : ${MAKE="make"} : ${MKDIR="mkdir"} : ${MV="mv -f"} : ${RM="rm -f"} : ${SHELL="${CONFIG_SHELL-/bin/sh}"} ## -------------------- ## ## Useful sed snippets. ## ## -------------------- ## sed_dirname='s|/[^/]*$||' sed_basename='s|^.*/||' # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. sed_quote_subst='s|\([`"$\\]\)|\\\1|g' # Same as above, but do not quote variable references. sed_double_quote_subst='s/\(["`\\]\)/\\\1/g' # Sed substitution that turns a string into a regex matching for the # string literally. sed_make_literal_regex='s|[].[^$\\*\/]|\\&|g' # Sed substitution that converts a w32 file name or path # that contains forward slashes, into one that contains # (escaped) backslashes. A very naive implementation. sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' # Re-'\' parameter expansions in output of sed_double_quote_subst that # were '\'-ed in input to the same. If an odd number of '\' preceded a # '$' in input to sed_double_quote_subst, that '$' was protected from # expansion. Since each input '\' is now two '\'s, look for any number # of runs of four '\'s followed by two '\'s and then a '$'. '\' that '$'. _G_bs='\\' _G_bs2='\\\\' _G_bs4='\\\\\\\\' _G_dollar='\$' sed_double_backslash="\ s/$_G_bs4/&\\ /g s/^$_G_bs2$_G_dollar/$_G_bs&/ s/\\([^$_G_bs]\\)$_G_bs2$_G_dollar/\\1$_G_bs2$_G_bs$_G_dollar/g s/\n//g" # require_check_ifs_backslash # --------------------------- # Check if we can use backslash as IFS='\' separator, and set # $check_ifs_backshlash_broken to ':' or 'false'. require_check_ifs_backslash=func_require_check_ifs_backslash func_require_check_ifs_backslash () { _G_save_IFS=$IFS IFS='\' _G_check_ifs_backshlash='a\\b' for _G_i in $_G_check_ifs_backshlash do case $_G_i in a) check_ifs_backshlash_broken=false ;; '') break ;; *) check_ifs_backshlash_broken=: break ;; esac done IFS=$_G_save_IFS require_check_ifs_backslash=: } ## ----------------- ## ## Global variables. ## ## ----------------- ## # Except for the global variables explicitly listed below, the following # functions in the '^func_' namespace, and the '^require_' namespace # variables initialised in the 'Resource management' section, sourcing # this file will not pollute your global namespace with anything # else. There's no portable way to scope variables in Bourne shell # though, so actually running these functions will sometimes place # results into a variable named after the function, and often use # temporary variables in the '^_G_' namespace. If you are careful to # avoid using those namespaces casually in your sourcing script, things # should continue to work as you expect. And, of course, you can freely # overwrite any of the functions or variables defined here before # calling anything to customize them. EXIT_SUCCESS=0 EXIT_FAILURE=1 EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. # Allow overriding, eg assuming that you follow the convention of # putting '$debug_cmd' at the start of all your functions, you can get # bash to show function call trace with: # # debug_cmd='echo "${FUNCNAME[0]} $*" >&2' bash your-script-name debug_cmd=${debug_cmd-":"} exit_cmd=: # By convention, finish your script with: # # exit $exit_status # # so that you can set exit_status to non-zero if you want to indicate # something went wrong during execution without actually bailing out at # the point of failure. exit_status=$EXIT_SUCCESS # Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh # is ksh but when the shell is invoked as "sh" and the current value of # the _XPG environment variable is not equal to 1 (one), the special # positional parameter $0, within a function call, is the name of the # function. progpath=$0 # The name of this program. progname=`$ECHO "$progpath" |$SED "$sed_basename"` # Make sure we have an absolute progpath for reexecution: case $progpath in [\\/]*|[A-Za-z]:\\*) ;; *[\\/]*) progdir=`$ECHO "$progpath" |$SED "$sed_dirname"` progdir=`cd "$progdir" && pwd` progpath=$progdir/$progname ;; *) _G_IFS=$IFS IFS=${PATH_SEPARATOR-:} for progdir in $PATH; do IFS=$_G_IFS test -x "$progdir/$progname" && break done IFS=$_G_IFS test -n "$progdir" || progdir=`pwd` progpath=$progdir/$progname ;; esac ## ----------------- ## ## Standard options. ## ## ----------------- ## # The following options affect the operation of the functions defined # below, and should be set appropriately depending on run-time para- # meters passed on the command line. opt_dry_run=false opt_quiet=false opt_verbose=false # Categories 'all' and 'none' are always available. Append any others # you will pass as the first argument to func_warning from your own # code. warning_categories= # By default, display warnings according to 'opt_warning_types'. Set # 'warning_func' to ':' to elide all warnings, or func_fatal_error to # treat the next displayed warning as a fatal error. warning_func=func_warn_and_continue # Set to 'all' to display all warnings, 'none' to suppress all # warnings, or a space delimited list of some subset of # 'warning_categories' to display only the listed warnings. opt_warning_types=all ## -------------------- ## ## Resource management. ## ## -------------------- ## # This section contains definitions for functions that each ensure a # particular resource (a file, or a non-empty configuration variable for # example) is available, and if appropriate to extract default values # from pertinent package files. Call them using their associated # 'require_*' variable to ensure that they are executed, at most, once. # # It's entirely deliberate that calling these functions can set # variables that don't obey the namespace limitations obeyed by the rest # of this file, in order that that they be as useful as possible to # callers. # require_term_colors # ------------------- # Allow display of bold text on terminals that support it. require_term_colors=func_require_term_colors func_require_term_colors () { $debug_cmd test -t 1 && { # COLORTERM and USE_ANSI_COLORS environment variables take # precedence, because most terminfo databases neglect to describe # whether color sequences are supported. test -n "${COLORTERM+set}" && : ${USE_ANSI_COLORS="1"} if test 1 = "$USE_ANSI_COLORS"; then # Standard ANSI escape sequences tc_reset='' tc_bold=''; tc_standout='' tc_red=''; tc_green='' tc_blue=''; tc_cyan='' else # Otherwise trust the terminfo database after all. test -n "`tput sgr0 2>/dev/null`" && { tc_reset=`tput sgr0` test -n "`tput bold 2>/dev/null`" && tc_bold=`tput bold` tc_standout=$tc_bold test -n "`tput smso 2>/dev/null`" && tc_standout=`tput smso` test -n "`tput setaf 1 2>/dev/null`" && tc_red=`tput setaf 1` test -n "`tput setaf 2 2>/dev/null`" && tc_green=`tput setaf 2` test -n "`tput setaf 4 2>/dev/null`" && tc_blue=`tput setaf 4` test -n "`tput setaf 5 2>/dev/null`" && tc_cyan=`tput setaf 5` } fi } require_term_colors=: } ## ----------------- ## ## Function library. ## ## ----------------- ## # This section contains a variety of useful functions to call in your # scripts. Take note of the portable wrappers for features provided by # some modern shells, which will fall back to slower equivalents on # less featureful shells. # func_append VAR VALUE # --------------------- # Append VALUE onto the existing contents of VAR. # We should try to minimise forks, especially on Windows where they are # unreasonably slow, so skip the feature probes when bash or zsh are # being used: if test set = "${BASH_VERSION+set}${ZSH_VERSION+set}"; then : ${_G_HAVE_ARITH_OP="yes"} : ${_G_HAVE_XSI_OPS="yes"} # The += operator was introduced in bash 3.1 case $BASH_VERSION in [12].* | 3.0 | 3.0*) ;; *) : ${_G_HAVE_PLUSEQ_OP="yes"} ;; esac fi # _G_HAVE_PLUSEQ_OP # Can be empty, in which case the shell is probed, "yes" if += is # useable or anything else if it does not work. test -z "$_G_HAVE_PLUSEQ_OP" \ && (eval 'x=a; x+=" b"; test "a b" = "$x"') 2>/dev/null \ && _G_HAVE_PLUSEQ_OP=yes if test yes = "$_G_HAVE_PLUSEQ_OP" then # This is an XSI compatible shell, allowing a faster implementation... eval 'func_append () { $debug_cmd eval "$1+=\$2" }' else # ...otherwise fall back to using expr, which is often a shell builtin. func_append () { $debug_cmd eval "$1=\$$1\$2" } fi # func_append_quoted VAR VALUE # ---------------------------- # Quote VALUE and append to the end of shell variable VAR, separated # by a space. if test yes = "$_G_HAVE_PLUSEQ_OP"; then eval 'func_append_quoted () { $debug_cmd func_quote_arg pretty "$2" eval "$1+=\\ \$func_quote_arg_result" }' else func_append_quoted () { $debug_cmd func_quote_arg pretty "$2" eval "$1=\$$1\\ \$func_quote_arg_result" } fi # func_append_uniq VAR VALUE # -------------------------- # Append unique VALUE onto the existing contents of VAR, assuming # entries are delimited by the first character of VALUE. For example: # # func_append_uniq options " --another-option option-argument" # # will only append to $options if " --another-option option-argument " # is not already present somewhere in $options already (note spaces at # each end implied by leading space in second argument). func_append_uniq () { $debug_cmd eval _G_current_value='`$ECHO $'$1'`' _G_delim=`expr "$2" : '\(.\)'` case $_G_delim$_G_current_value$_G_delim in *"$2$_G_delim"*) ;; *) func_append "$@" ;; esac } # func_arith TERM... # ------------------ # Set func_arith_result to the result of evaluating TERMs. test -z "$_G_HAVE_ARITH_OP" \ && (eval 'test 2 = $(( 1 + 1 ))') 2>/dev/null \ && _G_HAVE_ARITH_OP=yes if test yes = "$_G_HAVE_ARITH_OP"; then eval 'func_arith () { $debug_cmd func_arith_result=$(( $* )) }' else func_arith () { $debug_cmd func_arith_result=`expr "$@"` } fi # func_basename FILE # ------------------ # Set func_basename_result to FILE with everything up to and including # the last / stripped. if test yes = "$_G_HAVE_XSI_OPS"; then # If this shell supports suffix pattern removal, then use it to avoid # forking. Hide the definitions single quotes in case the shell chokes # on unsupported syntax... _b='func_basename_result=${1##*/}' _d='case $1 in */*) func_dirname_result=${1%/*}$2 ;; * ) func_dirname_result=$3 ;; esac' else # ...otherwise fall back to using sed. _b='func_basename_result=`$ECHO "$1" |$SED "$sed_basename"`' _d='func_dirname_result=`$ECHO "$1" |$SED "$sed_dirname"` if test "X$func_dirname_result" = "X$1"; then func_dirname_result=$3 else func_append func_dirname_result "$2" fi' fi eval 'func_basename () { $debug_cmd '"$_b"' }' # func_dirname FILE APPEND NONDIR_REPLACEMENT # ------------------------------------------- # Compute the dirname of FILE. If nonempty, add APPEND to the result, # otherwise set result to NONDIR_REPLACEMENT. eval 'func_dirname () { $debug_cmd '"$_d"' }' # func_dirname_and_basename FILE APPEND NONDIR_REPLACEMENT # -------------------------------------------------------- # Perform func_basename and func_dirname in a single function # call: # dirname: Compute the dirname of FILE. If nonempty, # add APPEND to the result, otherwise set result # to NONDIR_REPLACEMENT. # value returned in "$func_dirname_result" # basename: Compute filename of FILE. # value retuned in "$func_basename_result" # For efficiency, we do not delegate to the functions above but instead # duplicate the functionality here. eval 'func_dirname_and_basename () { $debug_cmd '"$_b"' '"$_d"' }' # func_echo ARG... # ---------------- # Echo program name prefixed message. func_echo () { $debug_cmd _G_message=$* func_echo_IFS=$IFS IFS=$nl for _G_line in $_G_message; do IFS=$func_echo_IFS $ECHO "$progname: $_G_line" done IFS=$func_echo_IFS } # func_echo_all ARG... # -------------------- # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "$*" } # func_echo_infix_1 INFIX ARG... # ------------------------------ # Echo program name, followed by INFIX on the first line, with any # additional lines not showing INFIX. func_echo_infix_1 () { $debug_cmd $require_term_colors _G_infix=$1; shift _G_indent=$_G_infix _G_prefix="$progname: $_G_infix: " _G_message=$* # Strip color escape sequences before counting printable length for _G_tc in "$tc_reset" "$tc_bold" "$tc_standout" "$tc_red" "$tc_green" "$tc_blue" "$tc_cyan" do test -n "$_G_tc" && { _G_esc_tc=`$ECHO "$_G_tc" | $SED "$sed_make_literal_regex"` _G_indent=`$ECHO "$_G_indent" | $SED "s|$_G_esc_tc||g"` } done _G_indent="$progname: "`echo "$_G_indent" | $SED 's|.| |g'`" " ## exclude from sc_prohibit_nested_quotes func_echo_infix_1_IFS=$IFS IFS=$nl for _G_line in $_G_message; do IFS=$func_echo_infix_1_IFS $ECHO "$_G_prefix$tc_bold$_G_line$tc_reset" >&2 _G_prefix=$_G_indent done IFS=$func_echo_infix_1_IFS } # func_error ARG... # ----------------- # Echo program name prefixed message to standard error. func_error () { $debug_cmd $require_term_colors func_echo_infix_1 " $tc_standout${tc_red}error$tc_reset" "$*" >&2 } # func_fatal_error ARG... # ----------------------- # Echo program name prefixed message to standard error, and exit. func_fatal_error () { $debug_cmd func_error "$*" exit $EXIT_FAILURE } # func_grep EXPRESSION FILENAME # ----------------------------- # Check whether EXPRESSION matches any line of FILENAME, without output. func_grep () { $debug_cmd $GREP "$1" "$2" >/dev/null 2>&1 } # func_len STRING # --------------- # Set func_len_result to the length of STRING. STRING may not # start with a hyphen. test -z "$_G_HAVE_XSI_OPS" \ && (eval 'x=a/b/c; test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \ && _G_HAVE_XSI_OPS=yes if test yes = "$_G_HAVE_XSI_OPS"; then eval 'func_len () { $debug_cmd func_len_result=${#1} }' else func_len () { $debug_cmd func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len` } fi # func_mkdir_p DIRECTORY-PATH # --------------------------- # Make sure the entire path to DIRECTORY-PATH is available. func_mkdir_p () { $debug_cmd _G_directory_path=$1 _G_dir_list= if test -n "$_G_directory_path" && test : != "$opt_dry_run"; then # Protect directory names starting with '-' case $_G_directory_path in -*) _G_directory_path=./$_G_directory_path ;; esac # While some portion of DIR does not yet exist... while test ! -d "$_G_directory_path"; do # ...make a list in topmost first order. Use a colon delimited # list incase some portion of path contains whitespace. _G_dir_list=$_G_directory_path:$_G_dir_list # If the last portion added has no slash in it, the list is done case $_G_directory_path in */*) ;; *) break ;; esac # ...otherwise throw away the child directory and loop _G_directory_path=`$ECHO "$_G_directory_path" | $SED -e "$sed_dirname"` done _G_dir_list=`$ECHO "$_G_dir_list" | $SED 's|:*$||'` func_mkdir_p_IFS=$IFS; IFS=: for _G_dir in $_G_dir_list; do IFS=$func_mkdir_p_IFS # mkdir can fail with a 'File exist' error if two processes # try to create one of the directories concurrently. Don't # stop in that case! $MKDIR "$_G_dir" 2>/dev/null || : done IFS=$func_mkdir_p_IFS # Bail out if we (or some other process) failed to create a directory. test -d "$_G_directory_path" || \ func_fatal_error "Failed to create '$1'" fi } # func_mktempdir [BASENAME] # ------------------------- # Make a temporary directory that won't clash with other running # libtool processes, and avoids race conditions if possible. If # given, BASENAME is the basename for that directory. func_mktempdir () { $debug_cmd _G_template=${TMPDIR-/tmp}/${1-$progname} if test : = "$opt_dry_run"; then # Return a directory name, but don't create it in dry-run mode _G_tmpdir=$_G_template-$$ else # If mktemp works, use that first and foremost _G_tmpdir=`mktemp -d "$_G_template-XXXXXXXX" 2>/dev/null` if test ! -d "$_G_tmpdir"; then # Failing that, at least try and use $RANDOM to avoid a race _G_tmpdir=$_G_template-${RANDOM-0}$$ func_mktempdir_umask=`umask` umask 0077 $MKDIR "$_G_tmpdir" umask $func_mktempdir_umask fi # If we're not in dry-run mode, bomb out on failure test -d "$_G_tmpdir" || \ func_fatal_error "cannot create temporary directory '$_G_tmpdir'" fi $ECHO "$_G_tmpdir" } # func_normal_abspath PATH # ------------------------ # Remove doubled-up and trailing slashes, "." path components, # and cancel out any ".." path components in PATH after making # it an absolute path. func_normal_abspath () { $debug_cmd # These SED scripts presuppose an absolute path with a trailing slash. _G_pathcar='s|^/\([^/]*\).*$|\1|' _G_pathcdr='s|^/[^/]*||' _G_removedotparts=':dotsl s|/\./|/|g t dotsl s|/\.$|/|' _G_collapseslashes='s|/\{1,\}|/|g' _G_finalslash='s|/*$|/|' # Start from root dir and reassemble the path. func_normal_abspath_result= func_normal_abspath_tpath=$1 func_normal_abspath_altnamespace= case $func_normal_abspath_tpath in "") # Empty path, that just means $cwd. func_stripname '' '/' "`pwd`" func_normal_abspath_result=$func_stripname_result return ;; # The next three entries are used to spot a run of precisely # two leading slashes without using negated character classes; # we take advantage of case's first-match behaviour. ///*) # Unusual form of absolute path, do nothing. ;; //*) # Not necessarily an ordinary path; POSIX reserves leading '//' # and for example Cygwin uses it to access remote file shares # over CIFS/SMB, so we conserve a leading double slash if found. func_normal_abspath_altnamespace=/ ;; /*) # Absolute path, do nothing. ;; *) # Relative path, prepend $cwd. func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath ;; esac # Cancel out all the simple stuff to save iterations. We also want # the path to end with a slash for ease of parsing, so make sure # there is one (and only one) here. func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$_G_removedotparts" -e "$_G_collapseslashes" -e "$_G_finalslash"` while :; do # Processed it all yet? if test / = "$func_normal_abspath_tpath"; then # If we ascended to the root using ".." the result may be empty now. if test -z "$func_normal_abspath_result"; then func_normal_abspath_result=/ fi break fi func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$_G_pathcar"` func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$_G_pathcdr"` # Figure out what to do with it case $func_normal_abspath_tcomponent in "") # Trailing empty path component, ignore it. ;; ..) # Parent dir; strip last assembled component from result. func_dirname "$func_normal_abspath_result" func_normal_abspath_result=$func_dirname_result ;; *) # Actual path component, append it. func_append func_normal_abspath_result "/$func_normal_abspath_tcomponent" ;; esac done # Restore leading double-slash if one was found on entry. func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result } # func_notquiet ARG... # -------------------- # Echo program name prefixed message only when not in quiet mode. func_notquiet () { $debug_cmd $opt_quiet || func_echo ${1+"$@"} # A bug in bash halts the script if the last line of a function # fails when set -e is in force, so we need another command to # work around that: : } # func_relative_path SRCDIR DSTDIR # -------------------------------- # Set func_relative_path_result to the relative path from SRCDIR to DSTDIR. func_relative_path () { $debug_cmd func_relative_path_result= func_normal_abspath "$1" func_relative_path_tlibdir=$func_normal_abspath_result func_normal_abspath "$2" func_relative_path_tbindir=$func_normal_abspath_result # Ascend the tree starting from libdir while :; do # check if we have found a prefix of bindir case $func_relative_path_tbindir in $func_relative_path_tlibdir) # found an exact match func_relative_path_tcancelled= break ;; $func_relative_path_tlibdir*) # found a matching prefix func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir" func_relative_path_tcancelled=$func_stripname_result if test -z "$func_relative_path_result"; then func_relative_path_result=. fi break ;; *) func_dirname $func_relative_path_tlibdir func_relative_path_tlibdir=$func_dirname_result if test -z "$func_relative_path_tlibdir"; then # Have to descend all the way to the root! func_relative_path_result=../$func_relative_path_result func_relative_path_tcancelled=$func_relative_path_tbindir break fi func_relative_path_result=../$func_relative_path_result ;; esac done # Now calculate path; take care to avoid doubling-up slashes. func_stripname '' '/' "$func_relative_path_result" func_relative_path_result=$func_stripname_result func_stripname '/' '/' "$func_relative_path_tcancelled" if test -n "$func_stripname_result"; then func_append func_relative_path_result "/$func_stripname_result" fi # Normalisation. If bindir is libdir, return '.' else relative path. if test -n "$func_relative_path_result"; then func_stripname './' '' "$func_relative_path_result" func_relative_path_result=$func_stripname_result fi test -n "$func_relative_path_result" || func_relative_path_result=. : } # func_quote_portable EVAL ARG # ---------------------------- # Internal function to portably implement func_quote_arg. Note that we still # keep attention to performance here so we as much as possible try to avoid # calling sed binary (so far O(N) complexity as long as func_append is O(1)). func_quote_portable () { $debug_cmd $require_check_ifs_backslash func_quote_portable_result=$2 # one-time-loop (easy break) while true do if $1; then func_quote_portable_result=`$ECHO "$2" | $SED \ -e "$sed_double_quote_subst" -e "$sed_double_backslash"` break fi # Quote for eval. case $func_quote_portable_result in *[\\\`\"\$]*) # Fallback to sed for $func_check_bs_ifs_broken=:, or when the string # contains the shell wildcard characters. case $check_ifs_backshlash_broken$func_quote_portable_result in :*|*[\[\*\?]*) func_quote_portable_result=`$ECHO "$func_quote_portable_result" \ | $SED "$sed_quote_subst"` break ;; esac func_quote_portable_old_IFS=$IFS for _G_char in '\' '`' '"' '$' do # STATE($1) PREV($2) SEPARATOR($3) set start "" "" func_quote_portable_result=dummy"$_G_char$func_quote_portable_result$_G_char"dummy IFS=$_G_char for _G_part in $func_quote_portable_result do case $1 in quote) func_append func_quote_portable_result "$3$2" set quote "$_G_part" "\\$_G_char" ;; start) set first "" "" func_quote_portable_result= ;; first) set quote "$_G_part" "" ;; esac done done IFS=$func_quote_portable_old_IFS ;; *) ;; esac break done func_quote_portable_unquoted_result=$func_quote_portable_result case $func_quote_portable_result in # double-quote args containing shell metacharacters to delay # word splitting, command substitution and variable expansion # for a subsequent eval. # many bourne shells cannot handle close brackets correctly # in scan sets, so we specify it separately. *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") func_quote_portable_result=\"$func_quote_portable_result\" ;; esac } # func_quotefast_eval ARG # ----------------------- # Quote one ARG (internal). This is equivalent to 'func_quote_arg eval ARG', # but optimized for speed. Result is stored in $func_quotefast_eval. if test xyes = `(x=; printf -v x %q yes; echo x"$x") 2>/dev/null`; then printf -v _GL_test_printf_tilde %q '~' if test '\~' = "$_GL_test_printf_tilde"; then func_quotefast_eval () { printf -v func_quotefast_eval_result %q "$1" } else # Broken older Bash implementations. Make those faster too if possible. func_quotefast_eval () { case $1 in '~'*) func_quote_portable false "$1" func_quotefast_eval_result=$func_quote_portable_result ;; *) printf -v func_quotefast_eval_result %q "$1" ;; esac } fi else func_quotefast_eval () { func_quote_portable false "$1" func_quotefast_eval_result=$func_quote_portable_result } fi # func_quote_arg MODEs ARG # ------------------------ # Quote one ARG to be evaled later. MODEs argument may contain zero or more # specifiers listed below separated by ',' character. This function returns two # values: # i) func_quote_arg_result # double-quoted (when needed), suitable for a subsequent eval # ii) func_quote_arg_unquoted_result # has all characters that are still active within double # quotes backslashified. Available only if 'unquoted' is specified. # # Available modes: # ---------------- # 'eval' (default) # - escape shell special characters # 'expand' # - the same as 'eval'; but do not quote variable references # 'pretty' # - request aesthetic output, i.e. '"a b"' instead of 'a\ b'. This might # be used later in func_quote to get output like: 'echo "a b"' instead # of 'echo a\ b'. This is slower than default on some shells. # 'unquoted' # - produce also $func_quote_arg_unquoted_result which does not contain # wrapping double-quotes. # # Examples for 'func_quote_arg pretty,unquoted string': # # string | *_result | *_unquoted_result # ------------+-----------------------+------------------- # " | \" | \" # a b | "a b" | a b # "a b" | "\"a b\"" | \"a b\" # * | "*" | * # z="${x-$y}" | "z=\"\${x-\$y}\"" | z=\"\${x-\$y}\" # # Examples for 'func_quote_arg pretty,unquoted,expand string': # # string | *_result | *_unquoted_result # --------------+---------------------+-------------------- # z="${x-$y}" | "z=\"${x-$y}\"" | z=\"${x-$y}\" func_quote_arg () { _G_quote_expand=false case ,$1, in *,expand,*) _G_quote_expand=: ;; esac case ,$1, in *,pretty,*|*,expand,*|*,unquoted,*) func_quote_portable $_G_quote_expand "$2" func_quote_arg_result=$func_quote_portable_result func_quote_arg_unquoted_result=$func_quote_portable_unquoted_result ;; *) # Faster quote-for-eval for some shells. func_quotefast_eval "$2" func_quote_arg_result=$func_quotefast_eval_result ;; esac } # func_quote MODEs ARGs... # ------------------------ # Quote all ARGs to be evaled later and join them into single command. See # func_quote_arg's description for more info. func_quote () { $debug_cmd _G_func_quote_mode=$1 ; shift func_quote_result= while test 0 -lt $#; do func_quote_arg "$_G_func_quote_mode" "$1" if test -n "$func_quote_result"; then func_append func_quote_result " $func_quote_arg_result" else func_append func_quote_result "$func_quote_arg_result" fi shift done } # func_stripname PREFIX SUFFIX NAME # --------------------------------- # strip PREFIX and SUFFIX from NAME, and store in func_stripname_result. # PREFIX and SUFFIX must not contain globbing or regex special # characters, hashes, percent signs, but SUFFIX may contain a leading # dot (in which case that matches only a dot). if test yes = "$_G_HAVE_XSI_OPS"; then eval 'func_stripname () { $debug_cmd # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are # positional parameters, so assign one to ordinary variable first. func_stripname_result=$3 func_stripname_result=${func_stripname_result#"$1"} func_stripname_result=${func_stripname_result%"$2"} }' else func_stripname () { $debug_cmd case $2 in .*) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%\\\\$2\$%%"`;; *) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%$2\$%%"`;; esac } fi # func_show_eval CMD [FAIL_EXP] # ----------------------------- # Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is # not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP # is given, then evaluate it. func_show_eval () { $debug_cmd _G_cmd=$1 _G_fail_exp=${2-':'} func_quote_arg pretty,expand "$_G_cmd" eval "func_notquiet $func_quote_arg_result" $opt_dry_run || { eval "$_G_cmd" _G_status=$? if test 0 -ne "$_G_status"; then eval "(exit $_G_status); $_G_fail_exp" fi } } # func_show_eval_locale CMD [FAIL_EXP] # ------------------------------------ # Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is # not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP # is given, then evaluate it. Use the saved locale for evaluation. func_show_eval_locale () { $debug_cmd _G_cmd=$1 _G_fail_exp=${2-':'} $opt_quiet || { func_quote_arg expand,pretty "$_G_cmd" eval "func_echo $func_quote_arg_result" } $opt_dry_run || { eval "$_G_user_locale $_G_cmd" _G_status=$? eval "$_G_safe_locale" if test 0 -ne "$_G_status"; then eval "(exit $_G_status); $_G_fail_exp" fi } } # func_tr_sh # ---------- # Turn $1 into a string suitable for a shell variable name. # Result is stored in $func_tr_sh_result. All characters # not in the set a-zA-Z0-9_ are replaced with '_'. Further, # if $1 begins with a digit, a '_' is prepended as well. func_tr_sh () { $debug_cmd case $1 in [0-9]* | *[!a-zA-Z0-9_]*) func_tr_sh_result=`$ECHO "$1" | $SED -e 's/^\([0-9]\)/_\1/' -e 's/[^a-zA-Z0-9_]/_/g'` ;; * ) func_tr_sh_result=$1 ;; esac } # func_verbose ARG... # ------------------- # Echo program name prefixed message in verbose mode only. func_verbose () { $debug_cmd $opt_verbose && func_echo "$*" : } # func_warn_and_continue ARG... # ----------------------------- # Echo program name prefixed warning message to standard error. func_warn_and_continue () { $debug_cmd $require_term_colors func_echo_infix_1 "${tc_red}warning$tc_reset" "$*" >&2 } # func_warning CATEGORY ARG... # ---------------------------- # Echo program name prefixed warning message to standard error. Warning # messages can be filtered according to CATEGORY, where this function # elides messages where CATEGORY is not listed in the global variable # 'opt_warning_types'. func_warning () { $debug_cmd # CATEGORY must be in the warning_categories list! case " $warning_categories " in *" $1 "*) ;; *) func_internal_error "invalid warning category '$1'" ;; esac _G_category=$1 shift case " $opt_warning_types " in *" $_G_category "*) $warning_func ${1+"$@"} ;; esac } # func_sort_ver VER1 VER2 # ----------------------- # 'sort -V' is not generally available. # Note this deviates from the version comparison in automake # in that it treats 1.5 < 1.5.0, and treats 1.4.4a < 1.4-p3a # but this should suffice as we won't be specifying old # version formats or redundant trailing .0 in bootstrap.conf. # If we did want full compatibility then we should probably # use m4_version_compare from autoconf. func_sort_ver () { $debug_cmd printf '%s\n%s\n' "$1" "$2" \ | sort -t. -k 1,1n -k 2,2n -k 3,3n -k 4,4n -k 5,5n -k 6,6n -k 7,7n -k 8,8n -k 9,9n } # func_lt_ver PREV CURR # --------------------- # Return true if PREV and CURR are in the correct order according to # func_sort_ver, otherwise false. Use it like this: # # func_lt_ver "$prev_ver" "$proposed_ver" || func_fatal_error "..." func_lt_ver () { $debug_cmd test "x$1" = x`func_sort_ver "$1" "$2" | $SED 1q` } # Local variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC" # time-stamp-time-zone: "UTC" # End: #! /bin/sh # A portable, pluggable option parser for Bourne shell. # Written by Gary V. Vaughan, 2010 # This is free software. There is NO warranty; not even for # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # # Copyright (C) 2010-2019, 2021 Bootstrap Authors # # This file is dual licensed under the terms of the MIT license # , and GPL version 2 or later # . You must apply one of # these licenses when using or redistributing this software or any of # the files within it. See the URLs above, or the file `LICENSE` # included in the Bootstrap distribution for the full license texts. # Please report bugs or propose patches to: # # Set a version string for this script. scriptversion=2019-02-19.15; # UTC ## ------ ## ## Usage. ## ## ------ ## # This file is a library for parsing options in your shell scripts along # with assorted other useful supporting features that you can make use # of too. # # For the simplest scripts you might need only: # # #!/bin/sh # . relative/path/to/funclib.sh # . relative/path/to/options-parser # scriptversion=1.0 # func_options ${1+"$@"} # eval set dummy "$func_options_result"; shift # ...rest of your script... # # In order for the '--version' option to work, you will need to have a # suitably formatted comment like the one at the top of this file # starting with '# Written by ' and ending with '# Copyright'. # # For '-h' and '--help' to work, you will also need a one line # description of your script's purpose in a comment directly above the # '# Written by ' line, like the one at the top of this file. # # The default options also support '--debug', which will turn on shell # execution tracing (see the comment above debug_cmd below for another # use), and '--verbose' and the func_verbose function to allow your script # to display verbose messages only when your user has specified # '--verbose'. # # After sourcing this file, you can plug in processing for additional # options by amending the variables from the 'Configuration' section # below, and following the instructions in the 'Option parsing' # section further down. ## -------------- ## ## Configuration. ## ## -------------- ## # You should override these variables in your script after sourcing this # file so that they reflect the customisations you have added to the # option parser. # The usage line for option parsing errors and the start of '-h' and # '--help' output messages. You can embed shell variables for delayed # expansion at the time the message is displayed, but you will need to # quote other shell meta-characters carefully to prevent them being # expanded when the contents are evaled. usage='$progpath [OPTION]...' # Short help message in response to '-h' and '--help'. Add to this or # override it after sourcing this library to reflect the full set of # options your script accepts. usage_message="\ --debug enable verbose shell tracing -W, --warnings=CATEGORY report the warnings falling in CATEGORY [all] -v, --verbose verbosely report processing --version print version information and exit -h, --help print short or long help message and exit " # Additional text appended to 'usage_message' in response to '--help'. long_help_message=" Warning categories include: 'all' show all warnings 'none' turn off all the warnings 'error' warnings are treated as fatal errors" # Help message printed before fatal option parsing errors. fatal_help="Try '\$progname --help' for more information." ## ------------------------- ## ## Hook function management. ## ## ------------------------- ## # This section contains functions for adding, removing, and running hooks # in the main code. A hook is just a list of function names that can be # run in order later on. # func_hookable FUNC_NAME # ----------------------- # Declare that FUNC_NAME will run hooks added with # 'func_add_hook FUNC_NAME ...'. func_hookable () { $debug_cmd func_append hookable_fns " $1" } # func_add_hook FUNC_NAME HOOK_FUNC # --------------------------------- # Request that FUNC_NAME call HOOK_FUNC before it returns. FUNC_NAME must # first have been declared "hookable" by a call to 'func_hookable'. func_add_hook () { $debug_cmd case " $hookable_fns " in *" $1 "*) ;; *) func_fatal_error "'$1' does not accept hook functions." ;; esac eval func_append ${1}_hooks '" $2"' } # func_remove_hook FUNC_NAME HOOK_FUNC # ------------------------------------ # Remove HOOK_FUNC from the list of hook functions to be called by # FUNC_NAME. func_remove_hook () { $debug_cmd eval ${1}_hooks='`$ECHO "\$'$1'_hooks" |$SED "s| '$2'||"`' } # func_propagate_result FUNC_NAME_A FUNC_NAME_B # --------------------------------------------- # If the *_result variable of FUNC_NAME_A _is set_, assign its value to # *_result variable of FUNC_NAME_B. func_propagate_result () { $debug_cmd func_propagate_result_result=: if eval "test \"\${${1}_result+set}\" = set" then eval "${2}_result=\$${1}_result" else func_propagate_result_result=false fi } # func_run_hooks FUNC_NAME [ARG]... # --------------------------------- # Run all hook functions registered to FUNC_NAME. # It's assumed that the list of hook functions contains nothing more # than a whitespace-delimited list of legal shell function names, and # no effort is wasted trying to catch shell meta-characters or preserve # whitespace. func_run_hooks () { $debug_cmd _G_rc_run_hooks=false case " $hookable_fns " in *" $1 "*) ;; *) func_fatal_error "'$1' does not support hook functions." ;; esac eval _G_hook_fns=\$$1_hooks; shift for _G_hook in $_G_hook_fns; do func_unset "${_G_hook}_result" eval $_G_hook '${1+"$@"}' func_propagate_result $_G_hook func_run_hooks if $func_propagate_result_result; then eval set dummy "$func_run_hooks_result"; shift fi done } ## --------------- ## ## Option parsing. ## ## --------------- ## # In order to add your own option parsing hooks, you must accept the # full positional parameter list from your hook function. You may remove # or edit any options that you action, and then pass back the remaining # unprocessed options in '_result', escaped # suitably for 'eval'. # # The '_result' variable is automatically unset # before your hook gets called; for best performance, only set the # *_result variable when necessary (i.e. don't call the 'func_quote' # function unnecessarily because it can be an expensive operation on some # machines). # # Like this: # # my_options_prep () # { # $debug_cmd # # # Extend the existing usage message. # usage_message=$usage_message' # -s, --silent don'\''t print informational messages # ' # # No change in '$@' (ignored completely by this hook). Leave # # my_options_prep_result variable intact. # } # func_add_hook func_options_prep my_options_prep # # # my_silent_option () # { # $debug_cmd # # args_changed=false # # # Note that, for efficiency, we parse as many options as we can # # recognise in a loop before passing the remainder back to the # # caller on the first unrecognised argument we encounter. # while test $# -gt 0; do # opt=$1; shift # case $opt in # --silent|-s) opt_silent=: # args_changed=: # ;; # # Separate non-argument short options: # -s*) func_split_short_opt "$_G_opt" # set dummy "$func_split_short_opt_name" \ # "-$func_split_short_opt_arg" ${1+"$@"} # shift # args_changed=: # ;; # *) # Make sure the first unrecognised option "$_G_opt" # # is added back to "$@" in case we need it later, # # if $args_changed was set to 'true'. # set dummy "$_G_opt" ${1+"$@"}; shift; break ;; # esac # done # # # Only call 'func_quote' here if we processed at least one argument. # if $args_changed; then # func_quote eval ${1+"$@"} # my_silent_option_result=$func_quote_result # fi # } # func_add_hook func_parse_options my_silent_option # # # my_option_validation () # { # $debug_cmd # # $opt_silent && $opt_verbose && func_fatal_help "\ # '--silent' and '--verbose' options are mutually exclusive." # } # func_add_hook func_validate_options my_option_validation # # You'll also need to manually amend $usage_message to reflect the extra # options you parse. It's preferable to append if you can, so that # multiple option parsing hooks can be added safely. # func_options_finish [ARG]... # ---------------------------- # Finishing the option parse loop (call 'func_options' hooks ATM). func_options_finish () { $debug_cmd func_run_hooks func_options ${1+"$@"} func_propagate_result func_run_hooks func_options_finish } # func_options [ARG]... # --------------------- # All the functions called inside func_options are hookable. See the # individual implementations for details. func_hookable func_options func_options () { $debug_cmd _G_options_quoted=false for my_func in options_prep parse_options validate_options options_finish do func_unset func_${my_func}_result func_unset func_run_hooks_result eval func_$my_func '${1+"$@"}' func_propagate_result func_$my_func func_options if $func_propagate_result_result; then eval set dummy "$func_options_result"; shift _G_options_quoted=: fi done $_G_options_quoted || { # As we (func_options) are top-level options-parser function and # nobody quoted "$@" for us yet, we need to do it explicitly for # caller. func_quote eval ${1+"$@"} func_options_result=$func_quote_result } } # func_options_prep [ARG]... # -------------------------- # All initialisations required before starting the option parse loop. # Note that when calling hook functions, we pass through the list of # positional parameters. If a hook function modifies that list, and # needs to propagate that back to rest of this script, then the complete # modified list must be put in 'func_run_hooks_result' before returning. func_hookable func_options_prep func_options_prep () { $debug_cmd # Option defaults: opt_verbose=false opt_warning_types= func_run_hooks func_options_prep ${1+"$@"} func_propagate_result func_run_hooks func_options_prep } # func_parse_options [ARG]... # --------------------------- # The main option parsing loop. func_hookable func_parse_options func_parse_options () { $debug_cmd _G_parse_options_requote=false # this just eases exit handling while test $# -gt 0; do # Defer to hook functions for initial option parsing, so they # get priority in the event of reusing an option name. func_run_hooks func_parse_options ${1+"$@"} func_propagate_result func_run_hooks func_parse_options if $func_propagate_result_result; then eval set dummy "$func_parse_options_result"; shift # Even though we may have changed "$@", we passed the "$@" array # down into the hook and it quoted it for us (because we are in # this if-branch). No need to quote it again. _G_parse_options_requote=false fi # Break out of the loop if we already parsed every option. test $# -gt 0 || break # We expect that one of the options parsed in this function matches # and thus we remove _G_opt from "$@" and need to re-quote. _G_match_parse_options=: _G_opt=$1 shift case $_G_opt in --debug|-x) debug_cmd='set -x' func_echo "enabling shell trace mode" >&2 $debug_cmd ;; --no-warnings|--no-warning|--no-warn) set dummy --warnings none ${1+"$@"} shift ;; --warnings|--warning|-W) if test $# = 0 && func_missing_arg $_G_opt; then _G_parse_options_requote=: break fi case " $warning_categories $1" in *" $1 "*) # trailing space prevents matching last $1 above func_append_uniq opt_warning_types " $1" ;; *all) opt_warning_types=$warning_categories ;; *none) opt_warning_types=none warning_func=: ;; *error) opt_warning_types=$warning_categories warning_func=func_fatal_error ;; *) func_fatal_error \ "unsupported warning category: '$1'" ;; esac shift ;; --verbose|-v) opt_verbose=: ;; --version) func_version ;; -\?|-h) func_usage ;; --help) func_help ;; # Separate optargs to long options (plugins may need this): --*=*) func_split_equals "$_G_opt" set dummy "$func_split_equals_lhs" \ "$func_split_equals_rhs" ${1+"$@"} shift ;; # Separate optargs to short options: -W*) func_split_short_opt "$_G_opt" set dummy "$func_split_short_opt_name" \ "$func_split_short_opt_arg" ${1+"$@"} shift ;; # Separate non-argument short options: -\?*|-h*|-v*|-x*) func_split_short_opt "$_G_opt" set dummy "$func_split_short_opt_name" \ "-$func_split_short_opt_arg" ${1+"$@"} shift ;; --) _G_parse_options_requote=: ; break ;; -*) func_fatal_help "unrecognised option: '$_G_opt'" ;; *) set dummy "$_G_opt" ${1+"$@"}; shift _G_match_parse_options=false break ;; esac if $_G_match_parse_options; then _G_parse_options_requote=: fi done if $_G_parse_options_requote; then # save modified positional parameters for caller func_quote eval ${1+"$@"} func_parse_options_result=$func_quote_result fi } # func_validate_options [ARG]... # ------------------------------ # Perform any sanity checks on option settings and/or unconsumed # arguments. func_hookable func_validate_options func_validate_options () { $debug_cmd # Display all warnings if -W was not given. test -n "$opt_warning_types" || opt_warning_types=" $warning_categories" func_run_hooks func_validate_options ${1+"$@"} func_propagate_result func_run_hooks func_validate_options # Bail if the options were screwed! $exit_cmd $EXIT_FAILURE } ## ----------------- ## ## Helper functions. ## ## ----------------- ## # This section contains the helper functions used by the rest of the # hookable option parser framework in ascii-betical order. # func_fatal_help ARG... # ---------------------- # Echo program name prefixed message to standard error, followed by # a help hint, and exit. func_fatal_help () { $debug_cmd eval \$ECHO \""Usage: $usage"\" eval \$ECHO \""$fatal_help"\" func_error ${1+"$@"} exit $EXIT_FAILURE } # func_help # --------- # Echo long help message to standard output and exit. func_help () { $debug_cmd func_usage_message $ECHO "$long_help_message" exit 0 } # func_missing_arg ARGNAME # ------------------------ # Echo program name prefixed message to standard error and set global # exit_cmd. func_missing_arg () { $debug_cmd func_error "Missing argument for '$1'." exit_cmd=exit } # func_split_equals STRING # ------------------------ # Set func_split_equals_lhs and func_split_equals_rhs shell variables # after splitting STRING at the '=' sign. test -z "$_G_HAVE_XSI_OPS" \ && (eval 'x=a/b/c; test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \ && _G_HAVE_XSI_OPS=yes if test yes = "$_G_HAVE_XSI_OPS" then # This is an XSI compatible shell, allowing a faster implementation... eval 'func_split_equals () { $debug_cmd func_split_equals_lhs=${1%%=*} func_split_equals_rhs=${1#*=} if test "x$func_split_equals_lhs" = "x$1"; then func_split_equals_rhs= fi }' else # ...otherwise fall back to using expr, which is often a shell builtin. func_split_equals () { $debug_cmd func_split_equals_lhs=`expr "x$1" : 'x\([^=]*\)'` func_split_equals_rhs= test "x$func_split_equals_lhs=" = "x$1" \ || func_split_equals_rhs=`expr "x$1" : 'x[^=]*=\(.*\)$'` } fi #func_split_equals # func_split_short_opt SHORTOPT # ----------------------------- # Set func_split_short_opt_name and func_split_short_opt_arg shell # variables after splitting SHORTOPT after the 2nd character. if test yes = "$_G_HAVE_XSI_OPS" then # This is an XSI compatible shell, allowing a faster implementation... eval 'func_split_short_opt () { $debug_cmd func_split_short_opt_arg=${1#??} func_split_short_opt_name=${1%"$func_split_short_opt_arg"} }' else # ...otherwise fall back to using expr, which is often a shell builtin. func_split_short_opt () { $debug_cmd func_split_short_opt_name=`expr "x$1" : 'x\(-.\)'` func_split_short_opt_arg=`expr "x$1" : 'x-.\(.*\)$'` } fi #func_split_short_opt # func_usage # ---------- # Echo short help message to standard output and exit. func_usage () { $debug_cmd func_usage_message $ECHO "Run '$progname --help |${PAGER-more}' for full usage" exit 0 } # func_usage_message # ------------------ # Echo short help message to standard output. func_usage_message () { $debug_cmd eval \$ECHO \""Usage: $usage"\" echo $SED -n 's|^# || /^Written by/{ x;p;x } h /^Written by/q' < "$progpath" echo eval \$ECHO \""$usage_message"\" } # func_version # ------------ # Echo version message to standard output and exit. # The version message is extracted from the calling file's header # comments, with leading '# ' stripped: # 1. First display the progname and version # 2. Followed by the header comment line matching /^# Written by / # 3. Then a blank line followed by the first following line matching # /^# Copyright / # 4. Immediately followed by any lines between the previous matches, # except lines preceding the intervening completely blank line. # For example, see the header comments of this file. func_version () { $debug_cmd printf '%s\n' "$progname $scriptversion" $SED -n ' /^# Written by /!b s|^# ||; p; n :fwd2blnk /./ { n b fwd2blnk } p; n :holdwrnt s|^# || s|^# *$|| /^Copyright /!{ /./H n b holdwrnt } s|\((C)\)[ 0-9,-]*[ ,-]\([1-9][0-9]* \)|\1 \2| G s|\(\n\)\n*|\1|g p; q' < "$progpath" exit $? } # Local variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-pattern: "30/scriptversion=%:y-%02m-%02d.%02H; # UTC" # time-stamp-time-zone: "UTC" # End: # Set a version string. scriptversion='(GNU libtool) 2.4.7' # func_echo ARG... # ---------------- # Libtool also displays the current mode in messages, so override # funclib.sh func_echo with this custom definition. func_echo () { $debug_cmd _G_message=$* func_echo_IFS=$IFS IFS=$nl for _G_line in $_G_message; do IFS=$func_echo_IFS $ECHO "$progname${opt_mode+: $opt_mode}: $_G_line" done IFS=$func_echo_IFS } # func_warning ARG... # ------------------- # Libtool warnings are not categorized, so override funclib.sh # func_warning with this simpler definition. func_warning () { $debug_cmd $warning_func ${1+"$@"} } ## ---------------- ## ## Options parsing. ## ## ---------------- ## # Hook in the functions to make sure our own options are parsed during # the option parsing loop. usage='$progpath [OPTION]... [MODE-ARG]...' # Short help message in response to '-h'. usage_message="Options: --config show all configuration variables --debug enable verbose shell tracing -n, --dry-run display commands without modifying any files --features display basic configuration information and exit --mode=MODE use operation mode MODE --no-warnings equivalent to '-Wnone' --preserve-dup-deps don't remove duplicate dependency libraries --quiet, --silent don't print informational messages --tag=TAG use configuration variables from tag TAG -v, --verbose print more informational messages than default --version print version information -W, --warnings=CATEGORY report the warnings falling in CATEGORY [all] -h, --help, --help-all print short, long, or detailed help message " # Additional text appended to 'usage_message' in response to '--help'. func_help () { $debug_cmd func_usage_message $ECHO "$long_help_message MODE must be one of the following: clean remove files from the build directory compile compile a source file into a libtool object execute automatically set library path, then run a program finish complete the installation of libtool libraries install install libraries or executables link create a library or an executable uninstall remove libraries from an installed directory MODE-ARGS vary depending on the MODE. When passed as first option, '--mode=MODE' may be abbreviated as 'MODE' or a unique abbreviation of that. Try '$progname --help --mode=MODE' for a more detailed description of MODE. When reporting a bug, please describe a test case to reproduce it and include the following information: host-triplet: $host shell: $SHELL compiler: $LTCC compiler flags: $LTCFLAGS linker: $LD (gnu? $with_gnu_ld) version: $progname $scriptversion Debian-2.4.7-5 automake: `($AUTOMAKE --version) 2>/dev/null |$SED 1q` autoconf: `($AUTOCONF --version) 2>/dev/null |$SED 1q` Report bugs to . GNU libtool home page: . General help using GNU software: ." exit 0 } # func_lo2o OBJECT-NAME # --------------------- # Transform OBJECT-NAME from a '.lo' suffix to the platform specific # object suffix. lo2o=s/\\.lo\$/.$objext/ o2lo=s/\\.$objext\$/.lo/ if test yes = "$_G_HAVE_XSI_OPS"; then eval 'func_lo2o () { case $1 in *.lo) func_lo2o_result=${1%.lo}.$objext ;; * ) func_lo2o_result=$1 ;; esac }' # func_xform LIBOBJ-OR-SOURCE # --------------------------- # Transform LIBOBJ-OR-SOURCE from a '.o' or '.c' (or otherwise) # suffix to a '.lo' libtool-object suffix. eval 'func_xform () { func_xform_result=${1%.*}.lo }' else # ...otherwise fall back to using sed. func_lo2o () { func_lo2o_result=`$ECHO "$1" | $SED "$lo2o"` } func_xform () { func_xform_result=`$ECHO "$1" | $SED 's|\.[^.]*$|.lo|'` } fi # func_fatal_configuration ARG... # ------------------------------- # Echo program name prefixed message to standard error, followed by # a configuration failure hint, and exit. func_fatal_configuration () { func_fatal_error ${1+"$@"} \ "See the $PACKAGE documentation for more information." \ "Fatal configuration error." } # func_config # ----------- # Display the configuration for all the tags in this script. func_config () { re_begincf='^# ### BEGIN LIBTOOL' re_endcf='^# ### END LIBTOOL' # Default configuration. $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath" # Now print the configurations for the tags. for tagname in $taglist; do $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath" done exit $? } # func_features # ------------- # Display the features supported by this script. func_features () { echo "host: $host" if test yes = "$build_libtool_libs"; then echo "enable shared libraries" else echo "disable shared libraries" fi if test yes = "$build_old_libs"; then echo "enable static libraries" else echo "disable static libraries" fi exit $? } # func_enable_tag TAGNAME # ----------------------- # Verify that TAGNAME is valid, and either flag an error and exit, or # enable the TAGNAME tag. We also add TAGNAME to the global $taglist # variable here. func_enable_tag () { # Global variable: tagname=$1 re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$" re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$" sed_extractcf=/$re_begincf/,/$re_endcf/p # Validate tagname. case $tagname in *[!-_A-Za-z0-9,/]*) func_fatal_error "invalid tag name: $tagname" ;; esac # Don't test for the "default" C tag, as we know it's # there but not specially marked. case $tagname in CC) ;; *) if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then taglist="$taglist $tagname" # Evaluate the configuration. Be careful to quote the path # and the sed script, to avoid splitting on whitespace, but # also don't use non-portable quotes within backquotes within # quotes we have to do it in 2 steps: extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` eval "$extractedcf" else func_error "ignoring unknown tag $tagname" fi ;; esac } # func_check_version_match # ------------------------ # Ensure that we are using m4 macros, and libtool script from the same # release of libtool. func_check_version_match () { if test "$package_revision" != "$macro_revision"; then if test "$VERSION" != "$macro_version"; then if test -z "$macro_version"; then cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: definition of this LT_INIT comes from an older release. $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: and run autoconf again. _LT_EOF else cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: definition of this LT_INIT comes from $PACKAGE $macro_version. $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: and run autoconf again. _LT_EOF fi else cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, $progname: but the definition of this LT_INIT comes from revision $macro_revision. $progname: You should recreate aclocal.m4 with macros from revision $package_revision $progname: of $PACKAGE $VERSION and run autoconf again. _LT_EOF fi exit $EXIT_MISMATCH fi } # libtool_options_prep [ARG]... # ----------------------------- # Preparation for options parsed by libtool. libtool_options_prep () { $debug_mode # Option defaults: opt_config=false opt_dlopen= opt_dry_run=false opt_help=false opt_mode= opt_preserve_dup_deps=false opt_quiet=false nonopt= preserve_args= _G_rc_lt_options_prep=: _G_rc_lt_options_prep=: # Shorthand for --mode=foo, only valid as the first argument case $1 in clean|clea|cle|cl) shift; set dummy --mode clean ${1+"$@"}; shift ;; compile|compil|compi|comp|com|co|c) shift; set dummy --mode compile ${1+"$@"}; shift ;; execute|execut|execu|exec|exe|ex|e) shift; set dummy --mode execute ${1+"$@"}; shift ;; finish|finis|fini|fin|fi|f) shift; set dummy --mode finish ${1+"$@"}; shift ;; install|instal|insta|inst|ins|in|i) shift; set dummy --mode install ${1+"$@"}; shift ;; link|lin|li|l) shift; set dummy --mode link ${1+"$@"}; shift ;; uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) shift; set dummy --mode uninstall ${1+"$@"}; shift ;; *) _G_rc_lt_options_prep=false ;; esac if $_G_rc_lt_options_prep; then # Pass back the list of options. func_quote eval ${1+"$@"} libtool_options_prep_result=$func_quote_result fi } func_add_hook func_options_prep libtool_options_prep # libtool_parse_options [ARG]... # --------------------------------- # Provide handling for libtool specific options. libtool_parse_options () { $debug_cmd _G_rc_lt_parse_options=false # Perform our own loop to consume as many options as possible in # each iteration. while test $# -gt 0; do _G_match_lt_parse_options=: _G_opt=$1 shift case $_G_opt in --dry-run|--dryrun|-n) opt_dry_run=: ;; --config) func_config ;; --dlopen|-dlopen) opt_dlopen="${opt_dlopen+$opt_dlopen }$1" shift ;; --preserve-dup-deps) opt_preserve_dup_deps=: ;; --features) func_features ;; --finish) set dummy --mode finish ${1+"$@"}; shift ;; --help) opt_help=: ;; --help-all) opt_help=': help-all' ;; --mode) test $# = 0 && func_missing_arg $_G_opt && break opt_mode=$1 case $1 in # Valid mode arguments: clean|compile|execute|finish|install|link|relink|uninstall) ;; # Catch anything else as an error *) func_error "invalid argument for $_G_opt" exit_cmd=exit break ;; esac shift ;; --no-silent|--no-quiet) opt_quiet=false func_append preserve_args " $_G_opt" ;; --no-warnings|--no-warning|--no-warn) opt_warning=false func_append preserve_args " $_G_opt" ;; --no-verbose) opt_verbose=false func_append preserve_args " $_G_opt" ;; --silent|--quiet) opt_quiet=: opt_verbose=false func_append preserve_args " $_G_opt" ;; --tag) test $# = 0 && func_missing_arg $_G_opt && break opt_tag=$1 func_append preserve_args " $_G_opt $1" func_enable_tag "$1" shift ;; --verbose|-v) opt_quiet=false opt_verbose=: func_append preserve_args " $_G_opt" ;; # An option not handled by this hook function: *) set dummy "$_G_opt" ${1+"$@"} ; shift _G_match_lt_parse_options=false break ;; esac $_G_match_lt_parse_options && _G_rc_lt_parse_options=: done if $_G_rc_lt_parse_options; then # save modified positional parameters for caller func_quote eval ${1+"$@"} libtool_parse_options_result=$func_quote_result fi } func_add_hook func_parse_options libtool_parse_options # libtool_validate_options [ARG]... # --------------------------------- # Perform any sanity checks on option settings and/or unconsumed # arguments. libtool_validate_options () { # save first non-option argument if test 0 -lt $#; then nonopt=$1 shift fi # preserve --debug test : = "$debug_cmd" || func_append preserve_args " --debug" case $host in # Solaris2 added to fix http://debbugs.gnu.org/cgi/bugreport.cgi?bug=16452 # see also: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59788 *cygwin* | *mingw* | *pw32* | *cegcc* | *solaris2* | *os2*) # don't eliminate duplications in $postdeps and $predeps opt_duplicate_compiler_generated_deps=: ;; *) opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps ;; esac $opt_help || { # Sanity checks first: func_check_version_match test yes != "$build_libtool_libs" \ && test yes != "$build_old_libs" \ && func_fatal_configuration "not configured to build any kind of library" # Darwin sucks eval std_shrext=\"$shrext_cmds\" # Only execute mode is allowed to have -dlopen flags. if test -n "$opt_dlopen" && test execute != "$opt_mode"; then func_error "unrecognized option '-dlopen'" $ECHO "$help" 1>&2 exit $EXIT_FAILURE fi # Change the help message to a mode-specific one. generic_help=$help help="Try '$progname --help --mode=$opt_mode' for more information." } # Pass back the unparsed argument list func_quote eval ${1+"$@"} libtool_validate_options_result=$func_quote_result } func_add_hook func_validate_options libtool_validate_options # Process options as early as possible so that --help and --version # can return quickly. func_options ${1+"$@"} eval set dummy "$func_options_result"; shift ## ----------- ## ## Main. ## ## ----------- ## magic='%%%MAGIC variable%%%' magic_exe='%%%MAGIC EXE variable%%%' # Global variables. extracted_archives= extracted_serial=0 # If this variable is set in any of the actions, the command in it # will be execed at the end. This prevents here-documents from being # left over by shells. exec_cmd= # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $1 _LTECHO_EOF' } # func_generated_by_libtool # True iff stdin has been generated by Libtool. This function is only # a basic sanity check; it will hardly flush out determined imposters. func_generated_by_libtool_p () { $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 } # func_lalib_p file # True iff FILE is a libtool '.la' library or '.lo' object file. # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_lalib_p () { test -f "$1" && $SED -e 4q "$1" 2>/dev/null | func_generated_by_libtool_p } # func_lalib_unsafe_p file # True iff FILE is a libtool '.la' library or '.lo' object file. # This function implements the same check as func_lalib_p without # resorting to external programs. To this end, it redirects stdin and # closes it afterwards, without saving the original file descriptor. # As a safety measure, use it only where a negative result would be # fatal anyway. Works if 'file' does not exist. func_lalib_unsafe_p () { lalib_p=no if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then for lalib_p_l in 1 2 3 4 do read lalib_p_line case $lalib_p_line in \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; esac done exec 0<&5 5<&- fi test yes = "$lalib_p" } # func_ltwrapper_script_p file # True iff FILE is a libtool wrapper script # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_script_p () { test -f "$1" && $lt_truncate_bin < "$1" 2>/dev/null | func_generated_by_libtool_p } # func_ltwrapper_executable_p file # True iff FILE is a libtool wrapper executable # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_executable_p () { func_ltwrapper_exec_suffix= case $1 in *.exe) ;; *) func_ltwrapper_exec_suffix=.exe ;; esac $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1 } # func_ltwrapper_scriptname file # Assumes file is an ltwrapper_executable # uses $file to determine the appropriate filename for a # temporary ltwrapper_script. func_ltwrapper_scriptname () { func_dirname_and_basename "$1" "" "." func_stripname '' '.exe' "$func_basename_result" func_ltwrapper_scriptname_result=$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper } # func_ltwrapper_p file # True iff FILE is a libtool wrapper script or wrapper executable # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_p () { func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1" } # func_execute_cmds commands fail_cmd # Execute tilde-delimited COMMANDS. # If FAIL_CMD is given, eval that upon failure. # FAIL_CMD may read-access the current command in variable CMD! func_execute_cmds () { $debug_cmd save_ifs=$IFS; IFS='~' for cmd in $1; do IFS=$sp$nl eval cmd=\"$cmd\" IFS=$save_ifs func_show_eval "$cmd" "${2-:}" done IFS=$save_ifs } # func_source file # Source FILE, adding directory component if necessary. # Note that it is not necessary on cygwin/mingw to append a dot to # FILE even if both FILE and FILE.exe exist: automatic-append-.exe # behavior happens only for exec(3), not for open(2)! Also, sourcing # 'FILE.' does not work on cygwin managed mounts. func_source () { $debug_cmd case $1 in */* | *\\*) . "$1" ;; *) . "./$1" ;; esac } # func_resolve_sysroot PATH # Replace a leading = in PATH with a sysroot. Store the result into # func_resolve_sysroot_result func_resolve_sysroot () { func_resolve_sysroot_result=$1 case $func_resolve_sysroot_result in =*) func_stripname '=' '' "$func_resolve_sysroot_result" func_resolve_sysroot_result=$lt_sysroot$func_stripname_result ;; esac } # func_replace_sysroot PATH # If PATH begins with the sysroot, replace it with = and # store the result into func_replace_sysroot_result. func_replace_sysroot () { case $lt_sysroot:$1 in ?*:"$lt_sysroot"*) func_stripname "$lt_sysroot" '' "$1" func_replace_sysroot_result='='$func_stripname_result ;; *) # Including no sysroot. func_replace_sysroot_result=$1 ;; esac } # func_infer_tag arg # Infer tagged configuration to use if any are available and # if one wasn't chosen via the "--tag" command line option. # Only attempt this if the compiler in the base compile # command doesn't match the default compiler. # arg is usually of the form 'gcc ...' func_infer_tag () { $debug_cmd if test -n "$available_tags" && test -z "$tagname"; then CC_quoted= for arg in $CC; do func_append_quoted CC_quoted "$arg" done CC_expanded=`func_echo_all $CC` CC_quoted_expanded=`func_echo_all $CC_quoted` case $@ in # Blanks in the command may have been stripped by the calling shell, # but not from the CC environment variable when configure was run. " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;; # Blanks at the start of $base_compile will cause this to fail # if we don't check for them as well. *) for z in $available_tags; do if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then # Evaluate the configuration. eval "`$SED -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" CC_quoted= for arg in $CC; do # Double-quote args containing other shell metacharacters. func_append_quoted CC_quoted "$arg" done CC_expanded=`func_echo_all $CC` CC_quoted_expanded=`func_echo_all $CC_quoted` case "$@ " in " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) # The compiler in the base compile command matches # the one in the tagged configuration. # Assume this is the tagged configuration we want. tagname=$z break ;; esac fi done # If $tagname still isn't set, then no tagged configuration # was found and let the user know that the "--tag" command # line option must be used. if test -z "$tagname"; then func_echo "unable to infer tagged configuration" func_fatal_error "specify a tag with '--tag'" # else # func_verbose "using $tagname tagged configuration" fi ;; esac fi } # func_write_libtool_object output_name pic_name nonpic_name # Create a libtool object file (analogous to a ".la" file), # but don't create it if we're doing a dry run. func_write_libtool_object () { write_libobj=$1 if test yes = "$build_libtool_libs"; then write_lobj=\'$2\' else write_lobj=none fi if test yes = "$build_old_libs"; then write_oldobj=\'$3\' else write_oldobj=none fi $opt_dry_run || { cat >${write_libobj}T </dev/null` if test "$?" -eq 0 && test -n "$func_convert_core_file_wine_to_w32_tmp"; then func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" | $SED -e "$sed_naive_backslashify"` else func_convert_core_file_wine_to_w32_result= fi fi } # end: func_convert_core_file_wine_to_w32 # func_convert_core_path_wine_to_w32 ARG # Helper function used by path conversion functions when $build is *nix, and # $host is mingw, cygwin, or some other w32 environment. Relies on a correctly # configured wine environment available, with the winepath program in $build's # $PATH. Assumes ARG has no leading or trailing path separator characters. # # ARG is path to be converted from $build format to win32. # Result is available in $func_convert_core_path_wine_to_w32_result. # Unconvertible file (directory) names in ARG are skipped; if no directory names # are convertible, then the result may be empty. func_convert_core_path_wine_to_w32 () { $debug_cmd # unfortunately, winepath doesn't convert paths, only file names func_convert_core_path_wine_to_w32_result= if test -n "$1"; then oldIFS=$IFS IFS=: for func_convert_core_path_wine_to_w32_f in $1; do IFS=$oldIFS func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f" if test -n "$func_convert_core_file_wine_to_w32_result"; then if test -z "$func_convert_core_path_wine_to_w32_result"; then func_convert_core_path_wine_to_w32_result=$func_convert_core_file_wine_to_w32_result else func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result" fi fi done IFS=$oldIFS fi } # end: func_convert_core_path_wine_to_w32 # func_cygpath ARGS... # Wrapper around calling the cygpath program via LT_CYGPATH. This is used when # when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2) # $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or # (2), returns the Cygwin file name or path in func_cygpath_result (input # file name or path is assumed to be in w32 format, as previously converted # from $build's *nix or MSYS format). In case (3), returns the w32 file name # or path in func_cygpath_result (input file name or path is assumed to be in # Cygwin format). Returns an empty string on error. # # ARGS are passed to cygpath, with the last one being the file name or path to # be converted. # # Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH # environment variable; do not put it in $PATH. func_cygpath () { $debug_cmd if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null` if test "$?" -ne 0; then # on failure, ensure result is empty func_cygpath_result= fi else func_cygpath_result= func_error "LT_CYGPATH is empty or specifies non-existent file: '$LT_CYGPATH'" fi } #end: func_cygpath # func_convert_core_msys_to_w32 ARG # Convert file name or path ARG from MSYS format to w32 format. Return # result in func_convert_core_msys_to_w32_result. func_convert_core_msys_to_w32 () { $debug_cmd # awkward: cmd appends spaces to result func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null | $SED -e 's/[ ]*$//' -e "$sed_naive_backslashify"` } #end: func_convert_core_msys_to_w32 # func_convert_file_check ARG1 ARG2 # Verify that ARG1 (a file name in $build format) was converted to $host # format in ARG2. Otherwise, emit an error message, but continue (resetting # func_to_host_file_result to ARG1). func_convert_file_check () { $debug_cmd if test -z "$2" && test -n "$1"; then func_error "Could not determine host file name corresponding to" func_error " '$1'" func_error "Continuing, but uninstalled executables may not work." # Fallback: func_to_host_file_result=$1 fi } # end func_convert_file_check # func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH # Verify that FROM_PATH (a path in $build format) was converted to $host # format in TO_PATH. Otherwise, emit an error message, but continue, resetting # func_to_host_file_result to a simplistic fallback value (see below). func_convert_path_check () { $debug_cmd if test -z "$4" && test -n "$3"; then func_error "Could not determine the host path corresponding to" func_error " '$3'" func_error "Continuing, but uninstalled executables may not work." # Fallback. This is a deliberately simplistic "conversion" and # should not be "improved". See libtool.info. if test "x$1" != "x$2"; then lt_replace_pathsep_chars="s|$1|$2|g" func_to_host_path_result=`echo "$3" | $SED -e "$lt_replace_pathsep_chars"` else func_to_host_path_result=$3 fi fi } # end func_convert_path_check # func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG # Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT # and appending REPL if ORIG matches BACKPAT. func_convert_path_front_back_pathsep () { $debug_cmd case $4 in $1 ) func_to_host_path_result=$3$func_to_host_path_result ;; esac case $4 in $2 ) func_append func_to_host_path_result "$3" ;; esac } # end func_convert_path_front_back_pathsep ################################################## # $build to $host FILE NAME CONVERSION FUNCTIONS # ################################################## # invoked via '$to_host_file_cmd ARG' # # In each case, ARG is the path to be converted from $build to $host format. # Result will be available in $func_to_host_file_result. # func_to_host_file ARG # Converts the file name ARG from $build format to $host format. Return result # in func_to_host_file_result. func_to_host_file () { $debug_cmd $to_host_file_cmd "$1" } # end func_to_host_file # func_to_tool_file ARG LAZY # converts the file name ARG from $build format to toolchain format. Return # result in func_to_tool_file_result. If the conversion in use is listed # in (the comma separated) LAZY, no conversion takes place. func_to_tool_file () { $debug_cmd case ,$2, in *,"$to_tool_file_cmd",*) func_to_tool_file_result=$1 ;; *) $to_tool_file_cmd "$1" func_to_tool_file_result=$func_to_host_file_result ;; esac } # end func_to_tool_file # func_convert_file_noop ARG # Copy ARG to func_to_host_file_result. func_convert_file_noop () { func_to_host_file_result=$1 } # end func_convert_file_noop # func_convert_file_msys_to_w32 ARG # Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic # conversion to w32 is not available inside the cwrapper. Returns result in # func_to_host_file_result. func_convert_file_msys_to_w32 () { $debug_cmd func_to_host_file_result=$1 if test -n "$1"; then func_convert_core_msys_to_w32 "$1" func_to_host_file_result=$func_convert_core_msys_to_w32_result fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_msys_to_w32 # func_convert_file_cygwin_to_w32 ARG # Convert file name ARG from Cygwin to w32 format. Returns result in # func_to_host_file_result. func_convert_file_cygwin_to_w32 () { $debug_cmd func_to_host_file_result=$1 if test -n "$1"; then # because $build is cygwin, we call "the" cygpath in $PATH; no need to use # LT_CYGPATH in this case. func_to_host_file_result=`cygpath -m "$1"` fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_cygwin_to_w32 # func_convert_file_nix_to_w32 ARG # Convert file name ARG from *nix to w32 format. Requires a wine environment # and a working winepath. Returns result in func_to_host_file_result. func_convert_file_nix_to_w32 () { $debug_cmd func_to_host_file_result=$1 if test -n "$1"; then func_convert_core_file_wine_to_w32 "$1" func_to_host_file_result=$func_convert_core_file_wine_to_w32_result fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_nix_to_w32 # func_convert_file_msys_to_cygwin ARG # Convert file name ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. # Returns result in func_to_host_file_result. func_convert_file_msys_to_cygwin () { $debug_cmd func_to_host_file_result=$1 if test -n "$1"; then func_convert_core_msys_to_w32 "$1" func_cygpath -u "$func_convert_core_msys_to_w32_result" func_to_host_file_result=$func_cygpath_result fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_msys_to_cygwin # func_convert_file_nix_to_cygwin ARG # Convert file name ARG from *nix to Cygwin format. Requires Cygwin installed # in a wine environment, working winepath, and LT_CYGPATH set. Returns result # in func_to_host_file_result. func_convert_file_nix_to_cygwin () { $debug_cmd func_to_host_file_result=$1 if test -n "$1"; then # convert from *nix to w32, then use cygpath to convert from w32 to cygwin. func_convert_core_file_wine_to_w32 "$1" func_cygpath -u "$func_convert_core_file_wine_to_w32_result" func_to_host_file_result=$func_cygpath_result fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_nix_to_cygwin ############################################# # $build to $host PATH CONVERSION FUNCTIONS # ############################################# # invoked via '$to_host_path_cmd ARG' # # In each case, ARG is the path to be converted from $build to $host format. # The result will be available in $func_to_host_path_result. # # Path separators are also converted from $build format to $host format. If # ARG begins or ends with a path separator character, it is preserved (but # converted to $host format) on output. # # All path conversion functions are named using the following convention: # file name conversion function : func_convert_file_X_to_Y () # path conversion function : func_convert_path_X_to_Y () # where, for any given $build/$host combination the 'X_to_Y' value is the # same. If conversion functions are added for new $build/$host combinations, # the two new functions must follow this pattern, or func_init_to_host_path_cmd # will break. # func_init_to_host_path_cmd # Ensures that function "pointer" variable $to_host_path_cmd is set to the # appropriate value, based on the value of $to_host_file_cmd. to_host_path_cmd= func_init_to_host_path_cmd () { $debug_cmd if test -z "$to_host_path_cmd"; then func_stripname 'func_convert_file_' '' "$to_host_file_cmd" to_host_path_cmd=func_convert_path_$func_stripname_result fi } # func_to_host_path ARG # Converts the path ARG from $build format to $host format. Return result # in func_to_host_path_result. func_to_host_path () { $debug_cmd func_init_to_host_path_cmd $to_host_path_cmd "$1" } # end func_to_host_path # func_convert_path_noop ARG # Copy ARG to func_to_host_path_result. func_convert_path_noop () { func_to_host_path_result=$1 } # end func_convert_path_noop # func_convert_path_msys_to_w32 ARG # Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic # conversion to w32 is not available inside the cwrapper. Returns result in # func_to_host_path_result. func_convert_path_msys_to_w32 () { $debug_cmd func_to_host_path_result=$1 if test -n "$1"; then # Remove leading and trailing path separator characters from ARG. MSYS # behavior is inconsistent here; cygpath turns them into '.;' and ';.'; # and winepath ignores them completely. func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" func_to_host_path_result=$func_convert_core_msys_to_w32_result func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_msys_to_w32 # func_convert_path_cygwin_to_w32 ARG # Convert path ARG from Cygwin to w32 format. Returns result in # func_to_host_file_result. func_convert_path_cygwin_to_w32 () { $debug_cmd func_to_host_path_result=$1 if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"` func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_cygwin_to_w32 # func_convert_path_nix_to_w32 ARG # Convert path ARG from *nix to w32 format. Requires a wine environment and # a working winepath. Returns result in func_to_host_file_result. func_convert_path_nix_to_w32 () { $debug_cmd func_to_host_path_result=$1 if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" func_to_host_path_result=$func_convert_core_path_wine_to_w32_result func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_nix_to_w32 # func_convert_path_msys_to_cygwin ARG # Convert path ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. # Returns result in func_to_host_file_result. func_convert_path_msys_to_cygwin () { $debug_cmd func_to_host_path_result=$1 if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" func_cygpath -u -p "$func_convert_core_msys_to_w32_result" func_to_host_path_result=$func_cygpath_result func_convert_path_check : : \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" : "$1" fi } # end func_convert_path_msys_to_cygwin # func_convert_path_nix_to_cygwin ARG # Convert path ARG from *nix to Cygwin format. Requires Cygwin installed in a # a wine environment, working winepath, and LT_CYGPATH set. Returns result in # func_to_host_file_result. func_convert_path_nix_to_cygwin () { $debug_cmd func_to_host_path_result=$1 if test -n "$1"; then # Remove leading and trailing path separator characters from # ARG. msys behavior is inconsistent here, cygpath turns them # into '.;' and ';.', and winepath ignores them completely. func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result" func_to_host_path_result=$func_cygpath_result func_convert_path_check : : \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" : "$1" fi } # end func_convert_path_nix_to_cygwin # func_dll_def_p FILE # True iff FILE is a Windows DLL '.def' file. # Keep in sync with _LT_DLL_DEF_P in libtool.m4 func_dll_def_p () { $debug_cmd func_dll_def_p_tmp=`$SED -n \ -e 's/^[ ]*//' \ -e '/^\(;.*\)*$/d' \ -e 's/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p' \ -e q \ "$1"` test DEF = "$func_dll_def_p_tmp" } # func_mode_compile arg... func_mode_compile () { $debug_cmd # Get the compilation command and the source file. base_compile= srcfile=$nonopt # always keep a non-empty value in "srcfile" suppress_opt=yes suppress_output= arg_mode=normal libobj= later= pie_flag= for arg do case $arg_mode in arg ) # do not "continue". Instead, add this to base_compile lastarg=$arg arg_mode=normal ;; target ) libobj=$arg arg_mode=normal continue ;; normal ) # Accept any command-line options. case $arg in -o) test -n "$libobj" && \ func_fatal_error "you cannot specify '-o' more than once" arg_mode=target continue ;; -pie | -fpie | -fPIE) func_append pie_flag " $arg" continue ;; -shared | -static | -prefer-pic | -prefer-non-pic) func_append later " $arg" continue ;; -no-suppress) suppress_opt=no continue ;; -Xcompiler) arg_mode=arg # the next one goes into the "base_compile" arg list continue # The current "srcfile" will either be retained or ;; # replaced later. I would guess that would be a bug. -Wc,*) func_stripname '-Wc,' '' "$arg" args=$func_stripname_result lastarg= save_ifs=$IFS; IFS=, for arg in $args; do IFS=$save_ifs func_append_quoted lastarg "$arg" done IFS=$save_ifs func_stripname ' ' '' "$lastarg" lastarg=$func_stripname_result # Add the arguments to base_compile. func_append base_compile " $lastarg" continue ;; *) # Accept the current argument as the source file. # The previous "srcfile" becomes the current argument. # lastarg=$srcfile srcfile=$arg ;; esac # case $arg ;; esac # case $arg_mode # Aesthetically quote the previous argument. func_append_quoted base_compile "$lastarg" done # for arg case $arg_mode in arg) func_fatal_error "you must specify an argument for -Xcompile" ;; target) func_fatal_error "you must specify a target with '-o'" ;; *) # Get the name of the library object. test -z "$libobj" && { func_basename "$srcfile" libobj=$func_basename_result } ;; esac # Recognize several different file suffixes. # If the user specifies -o file.o, it is replaced with file.lo case $libobj in *.[cCFSifmso] | \ *.ada | *.adb | *.ads | *.asm | \ *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \ *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup) func_xform "$libobj" libobj=$func_xform_result ;; esac case $libobj in *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;; *) func_fatal_error "cannot determine name of library object from '$libobj'" ;; esac func_infer_tag $base_compile for arg in $later; do case $arg in -shared) test yes = "$build_libtool_libs" \ || func_fatal_configuration "cannot build a shared library" build_old_libs=no continue ;; -static) build_libtool_libs=no build_old_libs=yes continue ;; -prefer-pic) pic_mode=yes continue ;; -prefer-non-pic) pic_mode=no continue ;; esac done func_quote_arg pretty "$libobj" test "X$libobj" != "X$func_quote_arg_result" \ && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \ && func_warning "libobj name '$libobj' may not contain shell special characters." func_dirname_and_basename "$obj" "/" "" objname=$func_basename_result xdir=$func_dirname_result lobj=$xdir$objdir/$objname test -z "$base_compile" && \ func_fatal_help "you must specify a compilation command" # Delete any leftover library objects. if test yes = "$build_old_libs"; then removelist="$obj $lobj $libobj ${libobj}T" else removelist="$lobj $libobj ${libobj}T" fi # On Cygwin there's no "real" PIC flag so we must build both object types case $host_os in cygwin* | mingw* | pw32* | os2* | cegcc*) pic_mode=default ;; esac if test no = "$pic_mode" && test pass_all != "$deplibs_check_method"; then # non-PIC code in shared libraries is not supported pic_mode=default fi # Calculate the filename of the output object if compiler does # not support -o with -c if test no = "$compiler_c_o"; then output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.$objext lockfile=$output_obj.lock else output_obj= need_locks=no lockfile= fi # Lock this critical section if it is needed # We use this script file to make the link, it avoids creating a new file if test yes = "$need_locks"; then until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do func_echo "Waiting for $lockfile to be removed" sleep 2 done elif test warn = "$need_locks"; then if test -f "$lockfile"; then $ECHO "\ *** ERROR, $lockfile exists and contains: `cat $lockfile 2>/dev/null` This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support '-c' and '-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi func_append removelist " $output_obj" $ECHO "$srcfile" > "$lockfile" fi $opt_dry_run || $RM $removelist func_append removelist " $lockfile" trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 func_to_tool_file "$srcfile" func_convert_file_msys_to_w32 srcfile=$func_to_tool_file_result func_quote_arg pretty "$srcfile" qsrcfile=$func_quote_arg_result # Only build a PIC object if we are building libtool libraries. if test yes = "$build_libtool_libs"; then # Without this assignment, base_compile gets emptied. fbsd_hideous_sh_bug=$base_compile if test no != "$pic_mode"; then command="$base_compile $qsrcfile $pic_flag" else # Don't build PIC code command="$base_compile $qsrcfile" fi func_mkdir_p "$xdir$objdir" if test -z "$output_obj"; then # Place PIC objects in $objdir func_append command " -o $lobj" fi func_show_eval_locale "$command" \ 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' if test warn = "$need_locks" && test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then $ECHO "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support '-c' and '-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi # Just move the object if needed, then go on to compile the next one if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then func_show_eval '$MV "$output_obj" "$lobj"' \ 'error=$?; $opt_dry_run || $RM $removelist; exit $error' fi # Allow error messages only from the first compilation. if test yes = "$suppress_opt"; then suppress_output=' >/dev/null 2>&1' fi fi # Only build a position-dependent object if we build old libraries. if test yes = "$build_old_libs"; then if test yes != "$pic_mode"; then # Don't build PIC code command="$base_compile $qsrcfile$pie_flag" else command="$base_compile $qsrcfile $pic_flag" fi if test yes = "$compiler_c_o"; then func_append command " -o $obj" fi # Suppress compiler output if we already did a PIC compilation. func_append command "$suppress_output" func_show_eval_locale "$command" \ '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' if test warn = "$need_locks" && test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then $ECHO "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support '-c' and '-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi # Just move the object if needed if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then func_show_eval '$MV "$output_obj" "$obj"' \ 'error=$?; $opt_dry_run || $RM $removelist; exit $error' fi fi $opt_dry_run || { func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" # Unlock the critical section if it was locked if test no != "$need_locks"; then removelist=$lockfile $RM "$lockfile" fi } exit $EXIT_SUCCESS } $opt_help || { test compile = "$opt_mode" && func_mode_compile ${1+"$@"} } func_mode_help () { # We need to display help for each of the modes. case $opt_mode in "") # Generic help is extracted from the usage comments # at the start of this file. func_help ;; clean) $ECHO \ "Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE... Remove files from the build directory. RM is the name of the program to use to delete files associated with each FILE (typically '/bin/rm'). RM-OPTIONS are options (such as '-f') to be passed to RM. If FILE is a libtool library, object or program, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; compile) $ECHO \ "Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE Compile a source file into a libtool library object. This mode accepts the following additional options: -o OUTPUT-FILE set the output file name to OUTPUT-FILE -no-suppress do not suppress compiler output for multiple passes -prefer-pic try to build PIC objects only -prefer-non-pic try to build non-PIC objects only -shared do not build a '.o' file suitable for static linking -static only build a '.o' file suitable for static linking -Wc,FLAG -Xcompiler FLAG pass FLAG directly to the compiler COMPILE-COMMAND is a command to be used in creating a 'standard' object file from the given SOURCEFILE. The output file name is determined by removing the directory component from SOURCEFILE, then substituting the C source code suffix '.c' with the library object suffix, '.lo'." ;; execute) $ECHO \ "Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]... Automatically set library path, then run a program. This mode accepts the following additional options: -dlopen FILE add the directory containing FILE to the library path This mode sets the library path environment variable according to '-dlopen' flags. If any of the ARGS are libtool executable wrappers, then they are translated into their corresponding uninstalled binary, and any of their required library directories are added to the library path. Then, COMMAND is executed, with ARGS as arguments." ;; finish) $ECHO \ "Usage: $progname [OPTION]... --mode=finish [LIBDIR]... Complete the installation of libtool libraries. Each LIBDIR is a directory that contains libtool libraries. The commands that this mode executes may require superuser privileges. Use the '--dry-run' option if you just want to see what would be executed." ;; install) $ECHO \ "Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND... Install executables or libraries. INSTALL-COMMAND is the installation command. The first component should be either the 'install' or 'cp' program. The following components of INSTALL-COMMAND are treated specially: -inst-prefix-dir PREFIX-DIR Use PREFIX-DIR as a staging area for installation The rest of the components are interpreted as arguments to that command (only BSD-compatible install options are recognized)." ;; link) $ECHO \ "Usage: $progname [OPTION]... --mode=link LINK-COMMAND... Link object files or libraries together to form another library, or to create an executable program. LINK-COMMAND is a command using the C compiler that you would use to create a program from several object files. The following components of LINK-COMMAND are treated specially: -all-static do not do any dynamic linking at all -avoid-version do not add a version suffix if possible -bindir BINDIR specify path to binaries directory (for systems where libraries must be found in the PATH setting at runtime) -dlopen FILE '-dlpreopen' FILE if it cannot be dlopened at runtime -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) -export-symbols SYMFILE try to export only the symbols listed in SYMFILE -export-symbols-regex REGEX try to export only the symbols matching REGEX -LLIBDIR search LIBDIR for required installed libraries -lNAME OUTPUT-FILE requires the installed library libNAME -module build a library that can dlopened -no-fast-install disable the fast-install mode -no-install link a not-installable executable -no-undefined declare that a library does not refer to external symbols -o OUTPUT-FILE create OUTPUT-FILE from the specified objects -objectlist FILE use a list of object files found in FILE to specify objects -os2dllname NAME force a short DLL name on OS/2 (no effect on other OSes) -precious-files-regex REGEX don't remove output files matching REGEX -release RELEASE specify package release information -rpath LIBDIR the created library will eventually be installed in LIBDIR -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries -shared only do dynamic linking of libtool libraries -shrext SUFFIX override the standard shared library file extension -static do not do any dynamic linking of uninstalled libtool libraries -static-libtool-libs do not do any dynamic linking of libtool libraries -version-info CURRENT[:REVISION[:AGE]] specify library version info [each variable defaults to 0] -weak LIBNAME declare that the target provides the LIBNAME interface -Wc,FLAG -Xcompiler FLAG pass linker-specific FLAG directly to the compiler -Wa,FLAG -Xassembler FLAG pass linker-specific FLAG directly to the assembler -Wl,FLAG -Xlinker FLAG pass linker-specific FLAG directly to the linker -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC) All other options (arguments beginning with '-') are ignored. Every other argument is treated as a filename. Files ending in '.la' are treated as uninstalled libtool libraries, other files are standard or library object files. If the OUTPUT-FILE ends in '.la', then a libtool library is created, only library objects ('.lo' files) may be specified, and '-rpath' is required, except when creating a convenience library. If OUTPUT-FILE ends in '.a' or '.lib', then a standard library is created using 'ar' and 'ranlib', or on Windows using 'lib'. If OUTPUT-FILE ends in '.lo' or '.$objext', then a reloadable object file is created, otherwise an executable program is created." ;; uninstall) $ECHO \ "Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... Remove libraries from an installation directory. RM is the name of the program to use to delete files associated with each FILE (typically '/bin/rm'). RM-OPTIONS are options (such as '-f') to be passed to RM. If FILE is a libtool library, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; *) func_fatal_help "invalid operation mode '$opt_mode'" ;; esac echo $ECHO "Try '$progname --help' for more information about other modes." } # Now that we've collected a possible --mode arg, show help if necessary if $opt_help; then if test : = "$opt_help"; then func_mode_help else { func_help noexit for opt_mode in compile link execute install finish uninstall clean; do func_mode_help done } | $SED -n '1p; 2,$s/^Usage:/ or: /p' { func_help noexit for opt_mode in compile link execute install finish uninstall clean; do echo func_mode_help done } | $SED '1d /^When reporting/,/^Report/{ H d } $x /information about other modes/d /more detailed .*MODE/d s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/' fi exit $? fi # func_mode_execute arg... func_mode_execute () { $debug_cmd # The first argument is the command name. cmd=$nonopt test -z "$cmd" && \ func_fatal_help "you must specify a COMMAND" # Handle -dlopen flags immediately. for file in $opt_dlopen; do test -f "$file" \ || func_fatal_help "'$file' is not a file" dir= case $file in *.la) func_resolve_sysroot "$file" file=$func_resolve_sysroot_result # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ || func_fatal_help "'$lib' is not a valid libtool archive" # Read the libtool library. dlname= library_names= func_source "$file" # Skip this library if it cannot be dlopened. if test -z "$dlname"; then # Warn if it was a shared library. test -n "$library_names" && \ func_warning "'$file' was not linked with '-export-dynamic'" continue fi func_dirname "$file" "" "." dir=$func_dirname_result if test -f "$dir/$objdir/$dlname"; then func_append dir "/$objdir" else if test ! -f "$dir/$dlname"; then func_fatal_error "cannot find '$dlname' in '$dir' or '$dir/$objdir'" fi fi ;; *.lo) # Just add the directory containing the .lo file. func_dirname "$file" "" "." dir=$func_dirname_result ;; *) func_warning "'-dlopen' is ignored for non-libtool libraries and objects" continue ;; esac # Get the absolute pathname. absdir=`cd "$dir" && pwd` test -n "$absdir" && dir=$absdir # Now add the directory to shlibpath_var. if eval "test -z \"\$$shlibpath_var\""; then eval "$shlibpath_var=\"\$dir\"" else eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" fi done # This variable tells wrapper scripts just to set shlibpath_var # rather than running their programs. libtool_execute_magic=$magic # Check if any of the arguments is a wrapper script. args= for file do case $file in -* | *.la | *.lo ) ;; *) # Do a test to see if this is really a libtool program. if func_ltwrapper_script_p "$file"; then func_source "$file" # Transform arg to wrapped name. file=$progdir/$program elif func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" func_source "$func_ltwrapper_scriptname_result" # Transform arg to wrapped name. file=$progdir/$program fi ;; esac # Quote arguments (to preserve shell metacharacters). func_append_quoted args "$file" done if $opt_dry_run; then # Display what would be done. if test -n "$shlibpath_var"; then eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" echo "export $shlibpath_var" fi $ECHO "$cmd$args" exit $EXIT_SUCCESS else if test -n "$shlibpath_var"; then # Export the shlibpath_var. eval "export $shlibpath_var" fi # Restore saved environment variables for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES do eval "if test \"\${save_$lt_var+set}\" = set; then $lt_var=\$save_$lt_var; export $lt_var else $lt_unset $lt_var fi" done # Now prepare to actually exec the command. exec_cmd=\$cmd$args fi } test execute = "$opt_mode" && func_mode_execute ${1+"$@"} # func_mode_finish arg... func_mode_finish () { $debug_cmd libs= libdirs= admincmds= for opt in "$nonopt" ${1+"$@"} do if test -d "$opt"; then func_append libdirs " $opt" elif test -f "$opt"; then if func_lalib_unsafe_p "$opt"; then func_append libs " $opt" else func_warning "'$opt' is not a valid libtool archive" fi else func_fatal_error "invalid argument '$opt'" fi done if test -n "$libs"; then if test -n "$lt_sysroot"; then sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"` sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;" else sysroot_cmd= fi # Remove sysroot references if $opt_dry_run; then for lib in $libs; do echo "removing references to $lt_sysroot and '=' prefixes from $lib" done else tmpdir=`func_mktempdir` for lib in $libs; do $SED -e "$sysroot_cmd s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \ > $tmpdir/tmp-la mv -f $tmpdir/tmp-la $lib done ${RM}r "$tmpdir" fi fi if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then for libdir in $libdirs; do if test -n "$finish_cmds"; then # Do each command in the finish commands. func_execute_cmds "$finish_cmds" 'admincmds="$admincmds '"$cmd"'"' fi if test -n "$finish_eval"; then # Do the single finish_eval. eval cmds=\"$finish_eval\" $opt_dry_run || eval "$cmds" || func_append admincmds " $cmds" fi done fi # Exit here if they wanted silent mode. $opt_quiet && exit $EXIT_SUCCESS if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then echo "----------------------------------------------------------------------" echo "Libraries have been installed in:" for libdir in $libdirs; do $ECHO " $libdir" done echo echo "If you ever happen to want to link against installed libraries" echo "in a given directory, LIBDIR, you must either use libtool, and" echo "specify the full pathname of the library, or use the '-LLIBDIR'" echo "flag during linking and do at least one of the following:" if test -n "$shlibpath_var"; then echo " - add LIBDIR to the '$shlibpath_var' environment variable" echo " during execution" fi if test -n "$runpath_var"; then echo " - add LIBDIR to the '$runpath_var' environment variable" echo " during linking" fi if test -n "$hardcode_libdir_flag_spec"; then libdir=LIBDIR eval flag=\"$hardcode_libdir_flag_spec\" $ECHO " - use the '$flag' linker flag" fi if test -n "$admincmds"; then $ECHO " - have your system administrator run these commands:$admincmds" fi if test -f /etc/ld.so.conf; then echo " - have your system administrator add LIBDIR to '/etc/ld.so.conf'" fi echo echo "See any operating system documentation about shared libraries for" case $host in solaris2.[6789]|solaris2.1[0-9]) echo "more information, such as the ld(1), crle(1) and ld.so(8) manual" echo "pages." ;; *) echo "more information, such as the ld(1) and ld.so(8) manual pages." ;; esac echo "----------------------------------------------------------------------" fi exit $EXIT_SUCCESS } test finish = "$opt_mode" && func_mode_finish ${1+"$@"} # func_mode_install arg... func_mode_install () { $debug_cmd # There may be an optional sh(1) argument at the beginning of # install_prog (especially on Windows NT). if test "$SHELL" = "$nonopt" || test /bin/sh = "$nonopt" || # Allow the use of GNU shtool's install command. case $nonopt in *shtool*) :;; *) false;; esac then # Aesthetically quote it. func_quote_arg pretty "$nonopt" install_prog="$func_quote_arg_result " arg=$1 shift else install_prog= arg=$nonopt fi # The real first argument should be the name of the installation program. # Aesthetically quote it. func_quote_arg pretty "$arg" func_append install_prog "$func_quote_arg_result" install_shared_prog=$install_prog case " $install_prog " in *[\\\ /]cp\ *) install_cp=: ;; *) install_cp=false ;; esac # We need to accept at least all the BSD install flags. dest= files= opts= prev= install_type= isdir=false stripme= no_mode=: for arg do arg2= if test -n "$dest"; then func_append files " $dest" dest=$arg continue fi case $arg in -d) isdir=: ;; -f) if $install_cp; then :; else prev=$arg fi ;; -g | -m | -o) prev=$arg ;; -s) stripme=" -s" continue ;; -*) ;; *) # If the previous option needed an argument, then skip it. if test -n "$prev"; then if test X-m = "X$prev" && test -n "$install_override_mode"; then arg2=$install_override_mode no_mode=false fi prev= else dest=$arg continue fi ;; esac # Aesthetically quote the argument. func_quote_arg pretty "$arg" func_append install_prog " $func_quote_arg_result" if test -n "$arg2"; then func_quote_arg pretty "$arg2" fi func_append install_shared_prog " $func_quote_arg_result" done test -z "$install_prog" && \ func_fatal_help "you must specify an install program" test -n "$prev" && \ func_fatal_help "the '$prev' option requires an argument" if test -n "$install_override_mode" && $no_mode; then if $install_cp; then :; else func_quote_arg pretty "$install_override_mode" func_append install_shared_prog " -m $func_quote_arg_result" fi fi if test -z "$files"; then if test -z "$dest"; then func_fatal_help "no file or destination specified" else func_fatal_help "you must specify a destination" fi fi # Strip any trailing slash from the destination. func_stripname '' '/' "$dest" dest=$func_stripname_result # Check to see that the destination is a directory. test -d "$dest" && isdir=: if $isdir; then destdir=$dest destname= else func_dirname_and_basename "$dest" "" "." destdir=$func_dirname_result destname=$func_basename_result # Not a directory, so check to see that there is only one file specified. set dummy $files; shift test "$#" -gt 1 && \ func_fatal_help "'$dest' is not a directory" fi case $destdir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) for file in $files; do case $file in *.lo) ;; *) func_fatal_help "'$destdir' must be an absolute directory name" ;; esac done ;; esac # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic=$magic staticlibs= future_libdirs= current_libdirs= for file in $files; do # Do each installation. case $file in *.$libext) # Do the static libraries later. func_append staticlibs " $file" ;; *.la) func_resolve_sysroot "$file" file=$func_resolve_sysroot_result # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ || func_fatal_help "'$file' is not a valid libtool archive" library_names= old_library= relink_command= func_source "$file" # Add the libdir to current_libdirs if it is the destination. if test "X$destdir" = "X$libdir"; then case "$current_libdirs " in *" $libdir "*) ;; *) func_append current_libdirs " $libdir" ;; esac else # Note the libdir as a future libdir. case "$future_libdirs " in *" $libdir "*) ;; *) func_append future_libdirs " $libdir" ;; esac fi func_dirname "$file" "/" "" dir=$func_dirname_result func_append dir "$objdir" if test -n "$relink_command"; then # Determine the prefix the user has applied to our future dir. inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"` # Don't allow the user to place us outside of our expected # location b/c this prevents finding dependent libraries that # are installed to the same prefix. # At present, this check doesn't affect windows .dll's that # are installed into $libdir/../bin (currently, that works fine) # but it's something to keep an eye on. test "$inst_prefix_dir" = "$destdir" && \ func_fatal_error "error: cannot install '$file' to a directory not ending in $libdir" if test -n "$inst_prefix_dir"; then # Stick the inst_prefix_dir data into the link command. relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` else relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"` fi func_warning "relinking '$file'" func_show_eval "$relink_command" \ 'func_fatal_error "error: relink '\''$file'\'' with the above command before installing it"' fi # See the names of the shared library. set dummy $library_names; shift if test -n "$1"; then realname=$1 shift srcname=$realname test -n "$relink_command" && srcname=${realname}T # Install the shared library and build the symlinks. func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \ 'exit $?' tstripme=$stripme case $host_os in cygwin* | mingw* | pw32* | cegcc*) case $realname in *.dll.a) tstripme= ;; esac ;; os2*) case $realname in *_dll.a) tstripme= ;; esac ;; esac if test -n "$tstripme" && test -n "$striplib"; then func_show_eval "$striplib $destdir/$realname" 'exit $?' fi if test "$#" -gt 0; then # Delete the old symlinks, and create new ones. # Try 'ln -sf' first, because the 'ln' binary might depend on # the symlink we replace! Solaris /bin/ln does not understand -f, # so we also need to try rm && ln -s. for linkname do test "$linkname" != "$realname" \ && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })" done fi # Do each command in the postinstall commands. lib=$destdir/$realname func_execute_cmds "$postinstall_cmds" 'exit $?' fi # Install the pseudo-library for information purposes. func_basename "$file" name=$func_basename_result instname=$dir/${name}i func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' # Maybe install the static library, too. test -n "$old_library" && func_append staticlibs " $dir/$old_library" ;; *.lo) # Install (i.e. copy) a libtool object. # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile=$destdir/$destname else func_basename "$file" destfile=$func_basename_result destfile=$destdir/$destfile fi # Deduce the name of the destination old-style object file. case $destfile in *.lo) func_lo2o "$destfile" staticdest=$func_lo2o_result ;; *.$objext) staticdest=$destfile destfile= ;; *) func_fatal_help "cannot copy a libtool object to '$destfile'" ;; esac # Install the libtool object if requested. test -n "$destfile" && \ func_show_eval "$install_prog $file $destfile" 'exit $?' # Install the old object if enabled. if test yes = "$build_old_libs"; then # Deduce the name of the old-style object file. func_lo2o "$file" staticobj=$func_lo2o_result func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?' fi exit $EXIT_SUCCESS ;; *) # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile=$destdir/$destname else func_basename "$file" destfile=$func_basename_result destfile=$destdir/$destfile fi # If the file is missing, and there is a .exe on the end, strip it # because it is most likely a libtool script we actually want to # install stripped_ext= case $file in *.exe) if test ! -f "$file"; then func_stripname '' '.exe' "$file" file=$func_stripname_result stripped_ext=.exe fi ;; esac # Do a test to see if this is really a libtool program. case $host in *cygwin* | *mingw*) if func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" wrapper=$func_ltwrapper_scriptname_result else func_stripname '' '.exe' "$file" wrapper=$func_stripname_result fi ;; *) wrapper=$file ;; esac if func_ltwrapper_script_p "$wrapper"; then notinst_deplibs= relink_command= func_source "$wrapper" # Check the variables that should have been set. test -z "$generated_by_libtool_version" && \ func_fatal_error "invalid libtool wrapper script '$wrapper'" finalize=: for lib in $notinst_deplibs; do # Check to see that each library is installed. libdir= if test -f "$lib"; then func_source "$lib" fi libfile=$libdir/`$ECHO "$lib" | $SED 's%^.*/%%g'` if test -n "$libdir" && test ! -f "$libfile"; then func_warning "'$lib' has not been installed in '$libdir'" finalize=false fi done relink_command= func_source "$wrapper" outputname= if test no = "$fast_install" && test -n "$relink_command"; then $opt_dry_run || { if $finalize; then tmpdir=`func_mktempdir` func_basename "$file$stripped_ext" file=$func_basename_result outputname=$tmpdir/$file # Replace the output file specification. relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'` $opt_quiet || { func_quote_arg expand,pretty "$relink_command" eval "func_echo $func_quote_arg_result" } if eval "$relink_command"; then : else func_error "error: relink '$file' with the above command before installing it" $opt_dry_run || ${RM}r "$tmpdir" continue fi file=$outputname else func_warning "cannot relink '$file'" fi } else # Install the binary that we compiled earlier. file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"` fi fi # remove .exe since cygwin /usr/bin/install will append another # one anyway case $install_prog,$host in */usr/bin/install*,*cygwin*) case $file:$destfile in *.exe:*.exe) # this is ok ;; *.exe:*) destfile=$destfile.exe ;; *:*.exe) func_stripname '' '.exe' "$destfile" destfile=$func_stripname_result ;; esac ;; esac func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?' $opt_dry_run || if test -n "$outputname"; then ${RM}r "$tmpdir" fi ;; esac done for file in $staticlibs; do func_basename "$file" name=$func_basename_result # Set up the ranlib parameters. oldlib=$destdir/$name func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 tool_oldlib=$func_to_tool_file_result func_show_eval "$install_prog \$file \$oldlib" 'exit $?' if test -n "$stripme" && test -n "$old_striplib"; then func_show_eval "$old_striplib $tool_oldlib" 'exit $?' fi # Do each command in the postinstall commands. func_execute_cmds "$old_postinstall_cmds" 'exit $?' done test -n "$future_libdirs" && \ func_warning "remember to run '$progname --finish$future_libdirs'" if test -n "$current_libdirs"; then # Maybe just do a dry run. $opt_dry_run && current_libdirs=" -n$current_libdirs" exec_cmd='$SHELL "$progpath" $preserve_args --finish$current_libdirs' else exit $EXIT_SUCCESS fi } test install = "$opt_mode" && func_mode_install ${1+"$@"} # func_generate_dlsyms outputname originator pic_p # Extract symbols from dlprefiles and create ${outputname}S.o with # a dlpreopen symbol table. func_generate_dlsyms () { $debug_cmd my_outputname=$1 my_originator=$2 my_pic_p=${3-false} my_prefix=`$ECHO "$my_originator" | $SED 's%[^a-zA-Z0-9]%_%g'` my_dlsyms= if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then if test -n "$NM" && test -n "$global_symbol_pipe"; then my_dlsyms=${my_outputname}S.c else func_error "not configured to extract global symbols from dlpreopened files" fi fi if test -n "$my_dlsyms"; then case $my_dlsyms in "") ;; *.c) # Discover the nlist of each of the dlfiles. nlist=$output_objdir/$my_outputname.nm func_show_eval "$RM $nlist ${nlist}S ${nlist}T" # Parse the name list into a source file. func_verbose "creating $output_objdir/$my_dlsyms" $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ /* $my_dlsyms - symbol resolution table for '$my_outputname' dlsym emulation. */ /* Generated by $PROGRAM (GNU $PACKAGE) $VERSION */ #ifdef __cplusplus extern \"C\" { #endif #if defined __GNUC__ && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4)) #pragma GCC diagnostic ignored \"-Wstrict-prototypes\" #endif /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE /* DATA imports from DLLs on WIN32 can't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT_DLSYM_CONST #elif defined __osf__ /* This system does not cope well with relocations in const data. */ # define LT_DLSYM_CONST #else # define LT_DLSYM_CONST const #endif #define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0) /* External symbol declarations for the compiler. */\ " if test yes = "$dlself"; then func_verbose "generating symbol list for '$output'" $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" # Add our own program objects to the symbol list. progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP` for progfile in $progfiles; do func_to_tool_file "$progfile" func_convert_file_msys_to_w32 func_verbose "extracting global C symbols from '$func_to_tool_file_result'" $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'" done if test -n "$exclude_expsyms"; then $opt_dry_run || { eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' } fi if test -n "$export_symbols_regex"; then $opt_dry_run || { eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' } fi # Prepare the list of exported symbols if test -z "$export_symbols"; then export_symbols=$output_objdir/$outputname.exp $opt_dry_run || { $RM $export_symbols eval "$SED -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' case $host in *cygwin* | *mingw* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' ;; esac } else $opt_dry_run || { eval "$SED -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' case $host in *cygwin* | *mingw* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' ;; esac } fi fi for dlprefile in $dlprefiles; do func_verbose "extracting global C symbols from '$dlprefile'" func_basename "$dlprefile" name=$func_basename_result case $host in *cygwin* | *mingw* | *cegcc* ) # if an import library, we need to obtain dlname if func_win32_import_lib_p "$dlprefile"; then func_tr_sh "$dlprefile" eval "curr_lafile=\$libfile_$func_tr_sh_result" dlprefile_dlbasename= if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then # Use subshell, to avoid clobbering current variable values dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"` if test -n "$dlprefile_dlname"; then func_basename "$dlprefile_dlname" dlprefile_dlbasename=$func_basename_result else # no lafile. user explicitly requested -dlpreopen . $sharedlib_from_linklib_cmd "$dlprefile" dlprefile_dlbasename=$sharedlib_from_linklib_result fi fi $opt_dry_run || { if test -n "$dlprefile_dlbasename"; then eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"' else func_warning "Could not compute DLL name from $name" eval '$ECHO ": $name " >> "$nlist"' fi func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe | $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'" } else # not an import lib $opt_dry_run || { eval '$ECHO ": $name " >> "$nlist"' func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" } fi ;; *) $opt_dry_run || { eval '$ECHO ": $name " >> "$nlist"' func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" } ;; esac done $opt_dry_run || { # Make sure we have at least an empty file. test -f "$nlist" || : > "$nlist" if test -n "$exclude_expsyms"; then $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T $MV "$nlist"T "$nlist" fi # Try sorting and uniquifying the output. if $GREP -v "^: " < "$nlist" | if sort -k 3 /dev/null 2>&1; then sort -k 3 else sort +2 fi | uniq > "$nlist"S; then : else $GREP -v "^: " < "$nlist" > "$nlist"S fi if test -f "$nlist"S; then eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"' else echo '/* NONE */' >> "$output_objdir/$my_dlsyms" fi func_show_eval '$RM "${nlist}I"' if test -n "$global_symbol_to_import"; then eval "$global_symbol_to_import"' < "$nlist"S > "$nlist"I' fi echo >> "$output_objdir/$my_dlsyms" "\ /* The mapping between symbol names and symbols. */ typedef struct { const char *name; void *address; } lt_dlsymlist; extern LT_DLSYM_CONST lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[];\ " if test -s "$nlist"I; then echo >> "$output_objdir/$my_dlsyms" "\ static void lt_syminit(void) { LT_DLSYM_CONST lt_dlsymlist *symbol = lt_${my_prefix}_LTX_preloaded_symbols; for (; symbol->name; ++symbol) {" $SED 's/.*/ if (STREQ (symbol->name, \"&\")) symbol->address = (void *) \&&;/' < "$nlist"I >> "$output_objdir/$my_dlsyms" echo >> "$output_objdir/$my_dlsyms" "\ } }" fi echo >> "$output_objdir/$my_dlsyms" "\ LT_DLSYM_CONST lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[] = { {\"$my_originator\", (void *) 0}," if test -s "$nlist"I; then echo >> "$output_objdir/$my_dlsyms" "\ {\"@INIT@\", (void *) <_syminit}," fi case $need_lib_prefix in no) eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms" ;; *) eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms" ;; esac echo >> "$output_objdir/$my_dlsyms" "\ {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt_${my_prefix}_LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif\ " } # !$opt_dry_run pic_flag_for_symtable= case "$compile_command " in *" -static "*) ;; *) case $host in # compiling the symbol table file with pic_flag works around # a FreeBSD bug that causes programs to crash when -lm is # linked before any other PIC object. But we must not use # pic_flag when linking with -static. The problem exists in # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; *-*-hpux*) pic_flag_for_symtable=" $pic_flag" ;; *) $my_pic_p && pic_flag_for_symtable=" $pic_flag" ;; esac ;; esac symtab_cflags= for arg in $LTCFLAGS; do case $arg in -pie | -fpie | -fPIE) ;; *) func_append symtab_cflags " $arg" ;; esac done # Now compile the dynamic symbol file. func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' # Clean up the generated files. func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T" "${nlist}I"' # Transform the symbol file into the correct name. symfileobj=$output_objdir/${my_outputname}S.$objext case $host in *cygwin* | *mingw* | *cegcc* ) if test -f "$output_objdir/$my_outputname.def"; then compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` else compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` fi ;; *) compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` ;; esac ;; *) func_fatal_error "unknown suffix for '$my_dlsyms'" ;; esac else # We keep going just in case the user didn't refer to # lt_preloaded_symbols. The linker will fail if global_symbol_pipe # really was required. # Nullify the symbol file. compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"` finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"` fi } # func_cygming_gnu_implib_p ARG # This predicate returns with zero status (TRUE) if # ARG is a GNU/binutils-style import library. Returns # with nonzero status (FALSE) otherwise. func_cygming_gnu_implib_p () { $debug_cmd func_to_tool_file "$1" func_convert_file_msys_to_w32 func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'` test -n "$func_cygming_gnu_implib_tmp" } # func_cygming_ms_implib_p ARG # This predicate returns with zero status (TRUE) if # ARG is an MS-style import library. Returns # with nonzero status (FALSE) otherwise. func_cygming_ms_implib_p () { $debug_cmd func_to_tool_file "$1" func_convert_file_msys_to_w32 func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'` test -n "$func_cygming_ms_implib_tmp" } # func_win32_libid arg # return the library type of file 'arg' # # Need a lot of goo to handle *both* DLLs and import libs # Has to be a shell function in order to 'eat' the argument # that is supplied when $file_magic_command is called. # Despite the name, also deal with 64 bit binaries. func_win32_libid () { $debug_cmd win32_libid_type=unknown win32_fileres=`file -L $1 2>/dev/null` case $win32_fileres in *ar\ archive\ import\ library*) # definitely import win32_libid_type="x86 archive import" ;; *ar\ archive*) # could be an import, or static # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD. if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then case $nm_interface in "MS dumpbin") if func_cygming_ms_implib_p "$1" || func_cygming_gnu_implib_p "$1" then win32_nmres=import else win32_nmres= fi ;; *) func_to_tool_file "$1" func_convert_file_msys_to_w32 win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" | $SED -n -e ' 1,100{ / I /{ s|.*|import| p q } }'` ;; esac case $win32_nmres in import*) win32_libid_type="x86 archive import";; *) win32_libid_type="x86 archive static";; esac fi ;; *DLL*) win32_libid_type="x86 DLL" ;; *executable*) # but shell scripts are "executable" too... case $win32_fileres in *MS\ Windows\ PE\ Intel*) win32_libid_type="x86 DLL" ;; esac ;; esac $ECHO "$win32_libid_type" } # func_cygming_dll_for_implib ARG # # Platform-specific function to extract the # name of the DLL associated with the specified # import library ARG. # Invoked by eval'ing the libtool variable # $sharedlib_from_linklib_cmd # Result is available in the variable # $sharedlib_from_linklib_result func_cygming_dll_for_implib () { $debug_cmd sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"` } # func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs # # The is the core of a fallback implementation of a # platform-specific function to extract the name of the # DLL associated with the specified import library LIBNAME. # # SECTION_NAME is either .idata$6 or .idata$7, depending # on the platform and compiler that created the implib. # # Echos the name of the DLL associated with the # specified import library. func_cygming_dll_for_implib_fallback_core () { $debug_cmd match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"` $OBJDUMP -s --section "$1" "$2" 2>/dev/null | $SED '/^Contents of section '"$match_literal"':/{ # Place marker at beginning of archive member dllname section s/.*/====MARK====/ p d } # These lines can sometimes be longer than 43 characters, but # are always uninteresting /:[ ]*file format pe[i]\{,1\}-/d /^In archive [^:]*:/d # Ensure marker is printed /^====MARK====/p # Remove all lines with less than 43 characters /^.\{43\}/!d # From remaining lines, remove first 43 characters s/^.\{43\}//' | $SED -n ' # Join marker and all lines until next marker into a single line /^====MARK====/ b para H $ b para b :para x s/\n//g # Remove the marker s/^====MARK====// # Remove trailing dots and whitespace s/[\. \t]*$// # Print /./p' | # we now have a list, one entry per line, of the stringified # contents of the appropriate section of all members of the # archive that possess that section. Heuristic: eliminate # all those that have a first or second character that is # a '.' (that is, objdump's representation of an unprintable # character.) This should work for all archives with less than # 0x302f exports -- but will fail for DLLs whose name actually # begins with a literal '.' or a single character followed by # a '.'. # # Of those that remain, print the first one. $SED -e '/^\./d;/^.\./d;q' } # func_cygming_dll_for_implib_fallback ARG # Platform-specific function to extract the # name of the DLL associated with the specified # import library ARG. # # This fallback implementation is for use when $DLLTOOL # does not support the --identify-strict option. # Invoked by eval'ing the libtool variable # $sharedlib_from_linklib_cmd # Result is available in the variable # $sharedlib_from_linklib_result func_cygming_dll_for_implib_fallback () { $debug_cmd if func_cygming_gnu_implib_p "$1"; then # binutils import library sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"` elif func_cygming_ms_implib_p "$1"; then # ms-generated import library sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"` else # unknown sharedlib_from_linklib_result= fi } # func_extract_an_archive dir oldlib func_extract_an_archive () { $debug_cmd f_ex_an_ar_dir=$1; shift f_ex_an_ar_oldlib=$1 if test yes = "$lock_old_archive_extraction"; then lockfile=$f_ex_an_ar_oldlib.lock until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do func_echo "Waiting for $lockfile to be removed" sleep 2 done fi func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \ 'stat=$?; rm -f "$lockfile"; exit $stat' if test yes = "$lock_old_archive_extraction"; then $opt_dry_run || rm -f "$lockfile" fi if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then : else func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" fi } # func_extract_archives gentop oldlib ... func_extract_archives () { $debug_cmd my_gentop=$1; shift my_oldlibs=${1+"$@"} my_oldobjs= my_xlib= my_xabs= my_xdir= for my_xlib in $my_oldlibs; do # Extract the objects. case $my_xlib in [\\/]* | [A-Za-z]:[\\/]*) my_xabs=$my_xlib ;; *) my_xabs=`pwd`"/$my_xlib" ;; esac func_basename "$my_xlib" my_xlib=$func_basename_result my_xlib_u=$my_xlib while :; do case " $extracted_archives " in *" $my_xlib_u "*) func_arith $extracted_serial + 1 extracted_serial=$func_arith_result my_xlib_u=lt$extracted_serial-$my_xlib ;; *) break ;; esac done extracted_archives="$extracted_archives $my_xlib_u" my_xdir=$my_gentop/$my_xlib_u func_mkdir_p "$my_xdir" case $host in *-darwin*) func_verbose "Extracting $my_xabs" # Do not bother doing anything if just a dry run $opt_dry_run || { darwin_orig_dir=`pwd` cd $my_xdir || exit $? darwin_archive=$my_xabs darwin_curdir=`pwd` func_basename "$darwin_archive" darwin_base_archive=$func_basename_result darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` if test -n "$darwin_arches"; then darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` darwin_arch= func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" for darwin_arch in $darwin_arches; do func_mkdir_p "unfat-$$/$darwin_base_archive-$darwin_arch" $LIPO -thin $darwin_arch -output "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" "$darwin_archive" cd "unfat-$$/$darwin_base_archive-$darwin_arch" func_extract_an_archive "`pwd`" "$darwin_base_archive" cd "$darwin_curdir" $RM "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" done # $darwin_arches ## Okay now we've a bunch of thin objects, gotta fatten them up :) darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$sed_basename" | sort -u` darwin_file= darwin_files= for darwin_file in $darwin_filelist; do darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP` $LIPO -create -output "$darwin_file" $darwin_files done # $darwin_filelist $RM -rf unfat-$$ cd "$darwin_orig_dir" else cd $darwin_orig_dir func_extract_an_archive "$my_xdir" "$my_xabs" fi # $darwin_arches } # !$opt_dry_run ;; *) func_extract_an_archive "$my_xdir" "$my_xabs" ;; esac my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP` done func_extract_archives_result=$my_oldobjs } # func_emit_wrapper [arg=no] # # Emit a libtool wrapper script on stdout. # Don't directly open a file because we may want to # incorporate the script contents within a cygwin/mingw # wrapper executable. Must ONLY be called from within # func_mode_link because it depends on a number of variables # set therein. # # ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR # variable will take. If 'yes', then the emitted script # will assume that the directory where it is stored is # the $objdir directory. This is a cygwin/mingw-specific # behavior. func_emit_wrapper () { func_emit_wrapper_arg1=${1-no} $ECHO "\ #! $SHELL # $output - temporary wrapper script for $objdir/$outputname # Generated by $PROGRAM (GNU $PACKAGE) $VERSION # # The $output program cannot be directly executed until all the libtool # libraries that it depends on are installed. # # This wrapper script should never be moved out of the build directory. # If it is, it will not operate correctly. # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. sed_quote_subst='$sed_quote_subst' # Be Bourne compatible if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac fi BIN_SH=xpg4; export BIN_SH # for Tru64 DUALCASE=1; export DUALCASE # for MKS sh # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH relink_command=\"$relink_command\" # This environment variable determines our operation mode. if test \"\$libtool_install_magic\" = \"$magic\"; then # install mode needs the following variables: generated_by_libtool_version='$macro_version' notinst_deplibs='$notinst_deplibs' else # When we are sourced in execute mode, \$file and \$ECHO are already set. if test \"\$libtool_execute_magic\" != \"$magic\"; then file=\"\$0\"" func_quote_arg pretty "$ECHO" qECHO=$func_quote_arg_result $ECHO "\ # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$1 _LTECHO_EOF' } ECHO=$qECHO fi # Very basic option parsing. These options are (a) specific to # the libtool wrapper, (b) are identical between the wrapper # /script/ and the wrapper /executable/ that is used only on # windows platforms, and (c) all begin with the string "--lt-" # (application programs are unlikely to have options that match # this pattern). # # There are only two supported options: --lt-debug and # --lt-dump-script. There is, deliberately, no --lt-help. # # The first argument to this parsing function should be the # script's $0 value, followed by "$@". lt_option_debug= func_parse_lt_options () { lt_script_arg0=\$0 shift for lt_opt do case \"\$lt_opt\" in --lt-debug) lt_option_debug=1 ;; --lt-dump-script) lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\` test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=. lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\` cat \"\$lt_dump_D/\$lt_dump_F\" exit 0 ;; --lt-*) \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2 exit 1 ;; esac done # Print the debug banner immediately: if test -n \"\$lt_option_debug\"; then echo \"$outputname:$output:\$LINENO: libtool wrapper (GNU $PACKAGE) $VERSION\" 1>&2 fi } # Used when --lt-debug. Prints its arguments to stdout # (redirection is the responsibility of the caller) func_lt_dump_args () { lt_dump_args_N=1; for lt_arg do \$ECHO \"$outputname:$output:\$LINENO: newargv[\$lt_dump_args_N]: \$lt_arg\" lt_dump_args_N=\`expr \$lt_dump_args_N + 1\` done } # Core function for launching the target application func_exec_program_core () { " case $host in # Backslashes separate directories on plain windows *-*-mingw | *-*-os2* | *-cegcc*) $ECHO "\ if test -n \"\$lt_option_debug\"; then \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir\\\\\$program\" 1>&2 func_lt_dump_args \${1+\"\$@\"} 1>&2 fi exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} " ;; *) $ECHO "\ if test -n \"\$lt_option_debug\"; then \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir/\$program\" 1>&2 func_lt_dump_args \${1+\"\$@\"} 1>&2 fi exec \"\$progdir/\$program\" \${1+\"\$@\"} " ;; esac $ECHO "\ \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2 exit 1 } # A function to encapsulate launching the target application # Strips options in the --lt-* namespace from \$@ and # launches target application with the remaining arguments. func_exec_program () { case \" \$* \" in *\\ --lt-*) for lt_wr_arg do case \$lt_wr_arg in --lt-*) ;; *) set x \"\$@\" \"\$lt_wr_arg\"; shift;; esac shift done ;; esac func_exec_program_core \${1+\"\$@\"} } # Parse options func_parse_lt_options \"\$0\" \${1+\"\$@\"} # Find the directory that this script lives in. thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\` test \"x\$thisdir\" = \"x\$file\" && thisdir=. # Follow symbolic links until we get to the real thisdir. file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\` while test -n \"\$file\"; do destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\` # If there was a directory component, then change thisdir. if test \"x\$destdir\" != \"x\$file\"; then case \"\$destdir\" in [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; *) thisdir=\"\$thisdir/\$destdir\" ;; esac fi file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\` file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\` done # Usually 'no', except on cygwin/mingw when embedded into # the cwrapper. WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1 if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then # special case for '.' if test \"\$thisdir\" = \".\"; then thisdir=\`pwd\` fi # remove .libs from thisdir case \"\$thisdir\" in *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;; $objdir ) thisdir=. ;; esac fi # Try to get the absolute directory name. absdir=\`cd \"\$thisdir\" && pwd\` test -n \"\$absdir\" && thisdir=\"\$absdir\" " if test yes = "$fast_install"; then $ECHO "\ program=lt-'$outputname'$exeext progdir=\"\$thisdir/$objdir\" if test ! -f \"\$progdir/\$program\" || { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | $SED 1q\`; \\ test \"X\$file\" != \"X\$progdir/\$program\"; }; then file=\"\$\$-\$program\" if test ! -d \"\$progdir\"; then $MKDIR \"\$progdir\" else $RM \"\$progdir/\$file\" fi" $ECHO "\ # relink executable if necessary if test -n \"\$relink_command\"; then if relink_command_output=\`eval \$relink_command 2>&1\`; then : else \$ECHO \"\$relink_command_output\" >&2 $RM \"\$progdir/\$file\" exit 1 fi fi $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || { $RM \"\$progdir/\$program\"; $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; } $RM \"\$progdir/\$file\" fi" else $ECHO "\ program='$outputname' progdir=\"\$thisdir/$objdir\" " fi $ECHO "\ if test -f \"\$progdir/\$program\"; then" # fixup the dll searchpath if we need to. # # Fix the DLL searchpath if we need to. Do this before prepending # to shlibpath, because on Windows, both are PATH and uninstalled # libraries must come first. if test -n "$dllsearchpath"; then $ECHO "\ # Add the dll search path components to the executable PATH PATH=$dllsearchpath:\$PATH " fi # Export our shlibpath_var if we have one. if test yes = "$shlibpath_overrides_runpath" && test -n "$shlibpath_var" && test -n "$temp_rpath"; then $ECHO "\ # Add our own library path to $shlibpath_var $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" # Some systems cannot cope with colon-terminated $shlibpath_var # The second colon is a workaround for a bug in BeOS R4 sed $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\` export $shlibpath_var " fi $ECHO "\ if test \"\$libtool_execute_magic\" != \"$magic\"; then # Run the actual program with our arguments. func_exec_program \${1+\"\$@\"} fi else # The program doesn't exist. \$ECHO \"\$0: error: '\$progdir/\$program' does not exist\" 1>&2 \$ECHO \"This script is just a wrapper for \$program.\" 1>&2 \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2 exit 1 fi fi\ " } # func_emit_cwrapperexe_src # emit the source code for a wrapper executable on stdout # Must ONLY be called from within func_mode_link because # it depends on a number of variable set therein. func_emit_cwrapperexe_src () { cat < #include #ifdef _MSC_VER # include # include # include #else # include # include # ifdef __CYGWIN__ # include # endif #endif #include #include #include #include #include #include #include #include #define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0) /* declarations of non-ANSI functions */ #if defined __MINGW32__ # ifdef __STRICT_ANSI__ int _putenv (const char *); # endif #elif defined __CYGWIN__ # ifdef __STRICT_ANSI__ char *realpath (const char *, char *); int putenv (char *); int setenv (const char *, const char *, int); # endif /* #elif defined other_platform || defined ... */ #endif /* portability defines, excluding path handling macros */ #if defined _MSC_VER # define setmode _setmode # define stat _stat # define chmod _chmod # define getcwd _getcwd # define putenv _putenv # define S_IXUSR _S_IEXEC #elif defined __MINGW32__ # define setmode _setmode # define stat _stat # define chmod _chmod # define getcwd _getcwd # define putenv _putenv #elif defined __CYGWIN__ # define HAVE_SETENV # define FOPEN_WB "wb" /* #elif defined other platforms ... */ #endif #if defined PATH_MAX # define LT_PATHMAX PATH_MAX #elif defined MAXPATHLEN # define LT_PATHMAX MAXPATHLEN #else # define LT_PATHMAX 1024 #endif #ifndef S_IXOTH # define S_IXOTH 0 #endif #ifndef S_IXGRP # define S_IXGRP 0 #endif /* path handling portability macros */ #ifndef DIR_SEPARATOR # define DIR_SEPARATOR '/' # define PATH_SEPARATOR ':' #endif #if defined _WIN32 || defined __MSDOS__ || defined __DJGPP__ || \ defined __OS2__ # define HAVE_DOS_BASED_FILE_SYSTEM # define FOPEN_WB "wb" # ifndef DIR_SEPARATOR_2 # define DIR_SEPARATOR_2 '\\' # endif # ifndef PATH_SEPARATOR_2 # define PATH_SEPARATOR_2 ';' # endif #endif #ifndef DIR_SEPARATOR_2 # define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) #else /* DIR_SEPARATOR_2 */ # define IS_DIR_SEPARATOR(ch) \ (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) #endif /* DIR_SEPARATOR_2 */ #ifndef PATH_SEPARATOR_2 # define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) #else /* PATH_SEPARATOR_2 */ # define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) #endif /* PATH_SEPARATOR_2 */ #ifndef FOPEN_WB # define FOPEN_WB "w" #endif #ifndef _O_BINARY # define _O_BINARY 0 #endif #define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) #define XFREE(stale) do { \ if (stale) { free (stale); stale = 0; } \ } while (0) #if defined LT_DEBUGWRAPPER static int lt_debug = 1; #else static int lt_debug = 0; #endif const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */ void *xmalloc (size_t num); char *xstrdup (const char *string); const char *base_name (const char *name); char *find_executable (const char *wrapper); char *chase_symlinks (const char *pathspec); int make_executable (const char *path); int check_executable (const char *path); char *strendzap (char *str, const char *pat); void lt_debugprintf (const char *file, int line, const char *fmt, ...); void lt_fatal (const char *file, int line, const char *message, ...); static const char *nonnull (const char *s); static const char *nonempty (const char *s); void lt_setenv (const char *name, const char *value); char *lt_extend_str (const char *orig_value, const char *add, int to_end); void lt_update_exe_path (const char *name, const char *value); void lt_update_lib_path (const char *name, const char *value); char **prepare_spawn (char **argv); void lt_dump_script (FILE *f); EOF cat <= 0) && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) return 1; else return 0; } int make_executable (const char *path) { int rval = 0; struct stat st; lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n", nonempty (path)); if ((!path) || (!*path)) return 0; if (stat (path, &st) >= 0) { rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR); } return rval; } /* Searches for the full path of the wrapper. Returns newly allocated full path name if found, NULL otherwise Does not chase symlinks, even on platforms that support them. */ char * find_executable (const char *wrapper) { int has_slash = 0; const char *p; const char *p_next; /* static buffer for getcwd */ char tmp[LT_PATHMAX + 1]; size_t tmp_len; char *concat_name; lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n", nonempty (wrapper)); if ((wrapper == NULL) || (*wrapper == '\0')) return NULL; /* Absolute path? */ #if defined HAVE_DOS_BASED_FILE_SYSTEM if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':') { concat_name = xstrdup (wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } else { #endif if (IS_DIR_SEPARATOR (wrapper[0])) { concat_name = xstrdup (wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } #if defined HAVE_DOS_BASED_FILE_SYSTEM } #endif for (p = wrapper; *p; p++) if (*p == '/') { has_slash = 1; break; } if (!has_slash) { /* no slashes; search PATH */ const char *path = getenv ("PATH"); if (path != NULL) { for (p = path; *p; p = p_next) { const char *q; size_t p_len; for (q = p; *q; q++) if (IS_PATH_SEPARATOR (*q)) break; p_len = (size_t) (q - p); p_next = (*q == '\0' ? q : q + 1); if (p_len == 0) { /* empty path: current directory */ if (getcwd (tmp, LT_PATHMAX) == NULL) lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", nonnull (strerror (errno))); tmp_len = strlen (tmp); concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, tmp, tmp_len); concat_name[tmp_len] = '/'; strcpy (concat_name + tmp_len + 1, wrapper); } else { concat_name = XMALLOC (char, p_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, p, p_len); concat_name[p_len] = '/'; strcpy (concat_name + p_len + 1, wrapper); } if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } } /* not found in PATH; assume curdir */ } /* Relative path | not found in path: prepend cwd */ if (getcwd (tmp, LT_PATHMAX) == NULL) lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", nonnull (strerror (errno))); tmp_len = strlen (tmp); concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, tmp, tmp_len); concat_name[tmp_len] = '/'; strcpy (concat_name + tmp_len + 1, wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); return NULL; } char * chase_symlinks (const char *pathspec) { #ifndef S_ISLNK return xstrdup (pathspec); #else char buf[LT_PATHMAX]; struct stat s; char *tmp_pathspec = xstrdup (pathspec); char *p; int has_symlinks = 0; while (strlen (tmp_pathspec) && !has_symlinks) { lt_debugprintf (__FILE__, __LINE__, "checking path component for symlinks: %s\n", tmp_pathspec); if (lstat (tmp_pathspec, &s) == 0) { if (S_ISLNK (s.st_mode) != 0) { has_symlinks = 1; break; } /* search backwards for last DIR_SEPARATOR */ p = tmp_pathspec + strlen (tmp_pathspec) - 1; while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) p--; if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) { /* no more DIR_SEPARATORS left */ break; } *p = '\0'; } else { lt_fatal (__FILE__, __LINE__, "error accessing file \"%s\": %s", tmp_pathspec, nonnull (strerror (errno))); } } XFREE (tmp_pathspec); if (!has_symlinks) { return xstrdup (pathspec); } tmp_pathspec = realpath (pathspec, buf); if (tmp_pathspec == 0) { lt_fatal (__FILE__, __LINE__, "could not follow symlinks for %s", pathspec); } return xstrdup (tmp_pathspec); #endif } char * strendzap (char *str, const char *pat) { size_t len, patlen; assert (str != NULL); assert (pat != NULL); len = strlen (str); patlen = strlen (pat); if (patlen <= len) { str += len - patlen; if (STREQ (str, pat)) *str = '\0'; } return str; } void lt_debugprintf (const char *file, int line, const char *fmt, ...) { va_list args; if (lt_debug) { (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line); va_start (args, fmt); (void) vfprintf (stderr, fmt, args); va_end (args); } } static void lt_error_core (int exit_status, const char *file, int line, const char *mode, const char *message, va_list ap) { fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode); vfprintf (stderr, message, ap); fprintf (stderr, ".\n"); if (exit_status >= 0) exit (exit_status); } void lt_fatal (const char *file, int line, const char *message, ...) { va_list ap; va_start (ap, message); lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap); va_end (ap); } static const char * nonnull (const char *s) { return s ? s : "(null)"; } static const char * nonempty (const char *s) { return (s && !*s) ? "(empty)" : nonnull (s); } void lt_setenv (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_setenv) setting '%s' to '%s'\n", nonnull (name), nonnull (value)); { #ifdef HAVE_SETENV /* always make a copy, for consistency with !HAVE_SETENV */ char *str = xstrdup (value); setenv (name, str, 1); #else size_t len = strlen (name) + 1 + strlen (value) + 1; char *str = XMALLOC (char, len); sprintf (str, "%s=%s", name, value); if (putenv (str) != EXIT_SUCCESS) { XFREE (str); } #endif } } char * lt_extend_str (const char *orig_value, const char *add, int to_end) { char *new_value; if (orig_value && *orig_value) { size_t orig_value_len = strlen (orig_value); size_t add_len = strlen (add); new_value = XMALLOC (char, add_len + orig_value_len + 1); if (to_end) { strcpy (new_value, orig_value); strcpy (new_value + orig_value_len, add); } else { strcpy (new_value, add); strcpy (new_value + add_len, orig_value); } } else { new_value = xstrdup (add); } return new_value; } void lt_update_exe_path (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_update_exe_path) modifying '%s' by prepending '%s'\n", nonnull (name), nonnull (value)); if (name && *name && value && *value) { char *new_value = lt_extend_str (getenv (name), value, 0); /* some systems can't cope with a ':'-terminated path #' */ size_t len = strlen (new_value); while ((len > 0) && IS_PATH_SEPARATOR (new_value[len-1])) { new_value[--len] = '\0'; } lt_setenv (name, new_value); XFREE (new_value); } } void lt_update_lib_path (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_update_lib_path) modifying '%s' by prepending '%s'\n", nonnull (name), nonnull (value)); if (name && *name && value && *value) { char *new_value = lt_extend_str (getenv (name), value, 0); lt_setenv (name, new_value); XFREE (new_value); } } EOF case $host_os in mingw*) cat <<"EOF" /* Prepares an argument vector before calling spawn(). Note that spawn() does not by itself call the command interpreter (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") : ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&v); v.dwPlatformId == VER_PLATFORM_WIN32_NT; }) ? "cmd.exe" : "command.com"). Instead it simply concatenates the arguments, separated by ' ', and calls CreateProcess(). We must quote the arguments since Win32 CreateProcess() interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a special way: - Space and tab are interpreted as delimiters. They are not treated as delimiters if they are surrounded by double quotes: "...". - Unescaped double quotes are removed from the input. Their only effect is that within double quotes, space and tab are treated like normal characters. - Backslashes not followed by double quotes are not special. - But 2*n+1 backslashes followed by a double quote become n backslashes followed by a double quote (n >= 0): \" -> " \\\" -> \" \\\\\" -> \\" */ #define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" #define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" char ** prepare_spawn (char **argv) { size_t argc; char **new_argv; size_t i; /* Count number of arguments. */ for (argc = 0; argv[argc] != NULL; argc++) ; /* Allocate new argument vector. */ new_argv = XMALLOC (char *, argc + 1); /* Put quoted arguments into the new argument vector. */ for (i = 0; i < argc; i++) { const char *string = argv[i]; if (string[0] == '\0') new_argv[i] = xstrdup ("\"\""); else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL) { int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL); size_t length; unsigned int backslashes; const char *s; char *quoted_string; char *p; length = 0; backslashes = 0; if (quote_around) length++; for (s = string; *s != '\0'; s++) { char c = *s; if (c == '"') length += backslashes + 1; length++; if (c == '\\') backslashes++; else backslashes = 0; } if (quote_around) length += backslashes + 1; quoted_string = XMALLOC (char, length + 1); p = quoted_string; backslashes = 0; if (quote_around) *p++ = '"'; for (s = string; *s != '\0'; s++) { char c = *s; if (c == '"') { unsigned int j; for (j = backslashes + 1; j > 0; j--) *p++ = '\\'; } *p++ = c; if (c == '\\') backslashes++; else backslashes = 0; } if (quote_around) { unsigned int j; for (j = backslashes; j > 0; j--) *p++ = '\\'; *p++ = '"'; } *p = '\0'; new_argv[i] = quoted_string; } else new_argv[i] = (char *) string; } new_argv[argc] = NULL; return new_argv; } EOF ;; esac cat <<"EOF" void lt_dump_script (FILE* f) { EOF func_emit_wrapper yes | $SED -n -e ' s/^\(.\{79\}\)\(..*\)/\1\ \2/ h s/\([\\"]\)/\\\1/g s/$/\\n/ s/\([^\n]*\).*/ fputs ("\1", f);/p g D' cat <<"EOF" } EOF } # end: func_emit_cwrapperexe_src # func_win32_import_lib_p ARG # True if ARG is an import lib, as indicated by $file_magic_cmd func_win32_import_lib_p () { $debug_cmd case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in *import*) : ;; *) false ;; esac } # func_suncc_cstd_abi # !!ONLY CALL THIS FOR SUN CC AFTER $compile_command IS FULLY EXPANDED!! # Several compiler flags select an ABI that is incompatible with the # Cstd library. Avoid specifying it if any are in CXXFLAGS. func_suncc_cstd_abi () { $debug_cmd case " $compile_command " in *" -compat=g "*|*\ -std=c++[0-9][0-9]\ *|*" -library=stdcxx4 "*|*" -library=stlport4 "*) suncc_use_cstd_abi=no ;; *) suncc_use_cstd_abi=yes ;; esac } # func_mode_link arg... func_mode_link () { $debug_cmd case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) # It is impossible to link a dll without this setting, and # we shouldn't force the makefile maintainer to figure out # what system we are compiling for in order to pass an extra # flag for every libtool invocation. # allow_undefined=no # FIXME: Unfortunately, there are problems with the above when trying # to make a dll that has undefined symbols, in which case not # even a static library is built. For now, we need to specify # -no-undefined on the libtool link line when we can be certain # that all symbols are satisfied, otherwise we get a static library. allow_undefined=yes ;; *) allow_undefined=yes ;; esac libtool_args=$nonopt base_compile="$nonopt $@" compile_command=$nonopt finalize_command=$nonopt compile_rpath= finalize_rpath= compile_shlibpath= finalize_shlibpath= convenience= old_convenience= deplibs= old_deplibs= compiler_flags= linker_flags= dllsearchpath= lib_search_path=`pwd` inst_prefix_dir= new_inherited_linker_flags= avoid_version=no bindir= dlfiles= dlprefiles= dlself=no export_dynamic=no export_symbols= export_symbols_regex= generated= libobjs= ltlibs= module=no no_install=no objs= os2dllname= non_pic_objects= precious_files_regex= prefer_static_libs=no preload=false prev= prevarg= release= rpath= xrpath= perm_rpath= temp_rpath= thread_safe=no vinfo= vinfo_number=no weak_libs= single_module=$wl-single_module func_infer_tag $base_compile # We need to know -static, to get the right output filenames. for arg do case $arg in -shared) test yes != "$build_libtool_libs" \ && func_fatal_configuration "cannot build a shared library" build_old_libs=no break ;; -all-static | -static | -static-libtool-libs) case $arg in -all-static) if test yes = "$build_libtool_libs" && test -z "$link_static_flag"; then func_warning "complete static linking is impossible in this configuration" fi if test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=yes ;; -static) if test -z "$pic_flag" && test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=built ;; -static-libtool-libs) if test -z "$pic_flag" && test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=yes ;; esac build_libtool_libs=no build_old_libs=yes break ;; esac done # See if our shared archives depend on static archives. test -n "$old_archive_from_new_cmds" && build_old_libs=yes # Go through the arguments, transforming them on the way. while test "$#" -gt 0; do arg=$1 shift func_quote_arg pretty,unquoted "$arg" qarg=$func_quote_arg_unquoted_result func_append libtool_args " $func_quote_arg_result" # If the previous option needs an argument, assign it. if test -n "$prev"; then case $prev in output) func_append compile_command " @OUTPUT@" func_append finalize_command " @OUTPUT@" ;; esac case $prev in bindir) bindir=$arg prev= continue ;; dlfiles|dlprefiles) $preload || { # Add the symbol object into the linking commands. func_append compile_command " @SYMFILE@" func_append finalize_command " @SYMFILE@" preload=: } case $arg in *.la | *.lo) ;; # We handle these cases below. force) if test no = "$dlself"; then dlself=needless export_dynamic=yes fi prev= continue ;; self) if test dlprefiles = "$prev"; then dlself=yes elif test dlfiles = "$prev" && test yes != "$dlopen_self"; then dlself=yes else dlself=needless export_dynamic=yes fi prev= continue ;; *) if test dlfiles = "$prev"; then func_append dlfiles " $arg" else func_append dlprefiles " $arg" fi prev= continue ;; esac ;; expsyms) export_symbols=$arg test -f "$arg" \ || func_fatal_error "symbol file '$arg' does not exist" prev= continue ;; expsyms_regex) export_symbols_regex=$arg prev= continue ;; framework) case $host in *-*-darwin*) case "$deplibs " in *" $qarg.ltframework "*) ;; *) func_append deplibs " $qarg.ltframework" # this is fixed later ;; esac ;; esac prev= continue ;; inst_prefix) inst_prefix_dir=$arg prev= continue ;; mllvm) # Clang does not use LLVM to link, so we can simply discard any # '-mllvm $arg' options when doing the link step. prev= continue ;; objectlist) if test -f "$arg"; then save_arg=$arg moreargs= for fil in `cat "$save_arg"` do # func_append moreargs " $fil" arg=$fil # A libtool-controlled object. # Check to see that this really is a libtool object. if func_lalib_unsafe_p "$arg"; then pic_object= non_pic_object= # Read the .lo file func_source "$arg" if test -z "$pic_object" || test -z "$non_pic_object" || test none = "$pic_object" && test none = "$non_pic_object"; then func_fatal_error "cannot find name of object for '$arg'" fi # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir=$func_dirname_result if test none != "$pic_object"; then # Prepend the subdirectory the object is found in. pic_object=$xdir$pic_object if test dlfiles = "$prev"; then if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then func_append dlfiles " $pic_object" prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi # CHECK ME: I think I busted this. -Ossama if test dlprefiles = "$prev"; then # Preload the old-style object. func_append dlprefiles " $pic_object" prev= fi # A PIC object. func_append libobjs " $pic_object" arg=$pic_object fi # Non-PIC object. if test none != "$non_pic_object"; then # Prepend the subdirectory the object is found in. non_pic_object=$xdir$non_pic_object # A standard non-PIC object func_append non_pic_objects " $non_pic_object" if test -z "$pic_object" || test none = "$pic_object"; then arg=$non_pic_object fi else # If the PIC object exists, use it instead. # $xdir was prepended to $pic_object above. non_pic_object=$pic_object func_append non_pic_objects " $non_pic_object" fi else # Only an error if not doing a dry-run. if $opt_dry_run; then # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir=$func_dirname_result func_lo2o "$arg" pic_object=$xdir$objdir/$func_lo2o_result non_pic_object=$xdir$func_lo2o_result func_append libobjs " $pic_object" func_append non_pic_objects " $non_pic_object" else func_fatal_error "'$arg' is not a valid libtool object" fi fi done else func_fatal_error "link input file '$arg' does not exist" fi arg=$save_arg prev= continue ;; os2dllname) os2dllname=$arg prev= continue ;; precious_regex) precious_files_regex=$arg prev= continue ;; release) release=-$arg prev= continue ;; rpath | xrpath) # We need an absolute path. case $arg in [\\/]* | [A-Za-z]:[\\/]*) ;; *) func_fatal_error "only absolute run-paths are allowed" ;; esac if test rpath = "$prev"; then case "$rpath " in *" $arg "*) ;; *) func_append rpath " $arg" ;; esac else case "$xrpath " in *" $arg "*) ;; *) func_append xrpath " $arg" ;; esac fi prev= continue ;; shrext) shrext_cmds=$arg prev= continue ;; weak) func_append weak_libs " $arg" prev= continue ;; xassembler) func_append compiler_flags " -Xassembler $qarg" prev= func_append compile_command " -Xassembler $qarg" func_append finalize_command " -Xassembler $qarg" continue ;; xcclinker) func_append linker_flags " $qarg" func_append compiler_flags " $qarg" prev= func_append compile_command " $qarg" func_append finalize_command " $qarg" continue ;; xcompiler) func_append compiler_flags " $qarg" prev= func_append compile_command " $qarg" func_append finalize_command " $qarg" continue ;; xlinker) func_append linker_flags " $qarg" func_append compiler_flags " $wl$qarg" prev= func_append compile_command " $wl$qarg" func_append finalize_command " $wl$qarg" continue ;; *) eval "$prev=\"\$arg\"" prev= continue ;; esac fi # test -n "$prev" prevarg=$arg case $arg in -all-static) if test -n "$link_static_flag"; then # See comment for -static flag below, for more details. func_append compile_command " $link_static_flag" func_append finalize_command " $link_static_flag" fi continue ;; -allow-undefined) # FIXME: remove this flag sometime in the future. func_fatal_error "'-allow-undefined' must not be used because it is the default" ;; -avoid-version) avoid_version=yes continue ;; -bindir) prev=bindir continue ;; -dlopen) prev=dlfiles continue ;; -dlpreopen) prev=dlprefiles continue ;; -export-dynamic) export_dynamic=yes continue ;; -export-symbols | -export-symbols-regex) if test -n "$export_symbols" || test -n "$export_symbols_regex"; then func_fatal_error "more than one -exported-symbols argument is not allowed" fi if test X-export-symbols = "X$arg"; then prev=expsyms else prev=expsyms_regex fi continue ;; -framework) prev=framework continue ;; -inst-prefix-dir) prev=inst_prefix continue ;; # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* # so, if we see these flags be careful not to treat them like -L -L[A-Z][A-Z]*:*) case $with_gcc/$host in no/*-*-irix* | /*-*-irix*) func_append compile_command " $arg" func_append finalize_command " $arg" ;; esac continue ;; -L*) func_stripname "-L" '' "$arg" if test -z "$func_stripname_result"; then if test "$#" -gt 0; then func_fatal_error "require no space between '-L' and '$1'" else func_fatal_error "need path for '-L' option" fi fi func_resolve_sysroot "$func_stripname_result" dir=$func_resolve_sysroot_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) absdir=`cd "$dir" && pwd` test -z "$absdir" && \ func_fatal_error "cannot determine absolute directory name of '$dir'" dir=$absdir ;; esac case "$deplibs " in *" -L$dir "* | *" $arg "*) # Will only happen for absolute or sysroot arguments ;; *) # Preserve sysroot, but never include relative directories case $dir in [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;; *) func_append deplibs " -L$dir" ;; esac func_append lib_search_path " $dir" ;; esac case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'` case :$dllsearchpath: in *":$dir:"*) ;; ::) dllsearchpath=$dir;; *) func_append dllsearchpath ":$dir";; esac case :$dllsearchpath: in *":$testbindir:"*) ;; ::) dllsearchpath=$testbindir;; *) func_append dllsearchpath ":$testbindir";; esac ;; esac continue ;; -l*) if test X-lc = "X$arg" || test X-lm = "X$arg"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*) # These systems don't actually have a C or math library (as such) continue ;; *-*-os2*) # These systems don't actually have a C library (as such) test X-lc = "X$arg" && continue ;; *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig* | *-*-midnightbsd*) # Do not include libc due to us having libc/libc_r. test X-lc = "X$arg" && continue ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C and math libraries are in the System framework func_append deplibs " System.ltframework" continue ;; *-*-sco3.2v5* | *-*-sco5v6*) # Causes problems with __ctype test X-lc = "X$arg" && continue ;; *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) # Compiler inserts libc in the correct place for threads to work test X-lc = "X$arg" && continue ;; esac elif test X-lc_r = "X$arg"; then case $host in *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig* | *-*-midnightbsd*) # Do not include libc_r directly, use -pthread flag. continue ;; esac fi func_append deplibs " $arg" continue ;; -mllvm) prev=mllvm continue ;; -module) module=yes continue ;; # Tru64 UNIX uses -model [arg] to determine the layout of C++ # classes, name mangling, and exception handling. # Darwin uses the -arch flag to determine output architecture. -model|-arch|-isysroot|--sysroot) func_append compiler_flags " $arg" func_append compile_command " $arg" func_append finalize_command " $arg" prev=xcompiler continue ;; # Solaris ld rejects as of 11.4. Refer to Oracle bug 22985199. -pthread) case $host in *solaris2*) ;; *) case "$new_inherited_linker_flags " in *" $arg "*) ;; * ) func_append new_inherited_linker_flags " $arg" ;; esac ;; esac continue ;; -mt|-mthreads|-kthread|-Kthread|-pthreads|--thread-safe \ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) func_append compiler_flags " $arg" func_append compile_command " $arg" func_append finalize_command " $arg" case "$new_inherited_linker_flags " in *" $arg "*) ;; * ) func_append new_inherited_linker_flags " $arg" ;; esac continue ;; -multi_module) single_module=$wl-multi_module continue ;; -no-fast-install) fast_install=no continue ;; -no-install) case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) # The PATH hackery in wrapper scripts is required on Windows # and Darwin in order for the loader to find any dlls it needs. func_warning "'-no-install' is ignored for $host" func_warning "assuming '-no-fast-install' instead" fast_install=no ;; *) no_install=yes ;; esac continue ;; -no-undefined) allow_undefined=no continue ;; -objectlist) prev=objectlist continue ;; -os2dllname) prev=os2dllname continue ;; -o) prev=output ;; -precious-files-regex) prev=precious_regex continue ;; -release) prev=release continue ;; -rpath) prev=rpath continue ;; -R) prev=xrpath continue ;; -R*) func_stripname '-R' '' "$arg" dir=$func_stripname_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; =*) func_stripname '=' '' "$dir" dir=$lt_sysroot$func_stripname_result ;; *) func_fatal_error "only absolute run-paths are allowed" ;; esac case "$xrpath " in *" $dir "*) ;; *) func_append xrpath " $dir" ;; esac continue ;; -shared) # The effects of -shared are defined in a previous loop. continue ;; -shrext) prev=shrext continue ;; -static | -static-libtool-libs) # The effects of -static are defined in a previous loop. # We used to do the same as -all-static on platforms that # didn't have a PIC flag, but the assumption that the effects # would be equivalent was wrong. It would break on at least # Digital Unix and AIX. continue ;; -thread-safe) thread_safe=yes continue ;; -version-info) prev=vinfo continue ;; -version-number) prev=vinfo vinfo_number=yes continue ;; -weak) prev=weak continue ;; -Wc,*) func_stripname '-Wc,' '' "$arg" args=$func_stripname_result arg= save_ifs=$IFS; IFS=, for flag in $args; do IFS=$save_ifs func_quote_arg pretty "$flag" func_append arg " $func_quote_arg_result" func_append compiler_flags " $func_quote_arg_result" done IFS=$save_ifs func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; -Wl,*) func_stripname '-Wl,' '' "$arg" args=$func_stripname_result arg= save_ifs=$IFS; IFS=, for flag in $args; do IFS=$save_ifs func_quote_arg pretty "$flag" func_append arg " $wl$func_quote_arg_result" func_append compiler_flags " $wl$func_quote_arg_result" func_append linker_flags " $func_quote_arg_result" done IFS=$save_ifs func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; -Xassembler) prev=xassembler continue ;; -Xcompiler) prev=xcompiler continue ;; -Xlinker) prev=xlinker continue ;; -XCClinker) prev=xcclinker continue ;; # -msg_* for osf cc -msg_*) func_quote_arg pretty "$arg" arg=$func_quote_arg_result ;; # Flags to be passed through unchanged, with rationale: # -64, -mips[0-9] enable 64-bit mode for the SGI compiler # -r[0-9][0-9]* specify processor for the SGI compiler # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler # +DA*, +DD* enable 64-bit mode for the HP compiler # -q* compiler args for the IBM compiler # -m*, -t[45]*, -txscale* architecture-specific flags for GCC # -F/path path to uninstalled frameworks, gcc on darwin # -p, -pg, --coverage, -fprofile-* profiling flags for GCC # -fstack-protector* stack protector flags for GCC # @file GCC response files # -tp=* Portland pgcc target processor selection # --sysroot=* for sysroot support # -O*, -g*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization # -specs=* GCC specs files # -stdlib=* select c++ std lib with clang # -fsanitize=* Clang/GCC memory and address sanitizer # -fuse-ld=* Linker select flags for GCC # -static-* direct GCC to link specific libraries statically # -fcilkplus Cilk Plus language extension features for C/C++ # -Wa,* Pass flags directly to the assembler -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \ -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*| \ -specs=*|-fsanitize=*|-fuse-ld=*|-static-*|-fcilkplus|-Wa,*) func_quote_arg pretty "$arg" arg=$func_quote_arg_result func_append compile_command " $arg" func_append finalize_command " $arg" func_append compiler_flags " $arg" continue ;; -Z*) if test os2 = "`expr $host : '.*\(os2\)'`"; then # OS/2 uses -Zxxx to specify OS/2-specific options compiler_flags="$compiler_flags $arg" func_append compile_command " $arg" func_append finalize_command " $arg" case $arg in -Zlinker | -Zstack) prev=xcompiler ;; esac continue else # Otherwise treat like 'Some other compiler flag' below func_quote_arg pretty "$arg" arg=$func_quote_arg_result fi ;; # Some other compiler flag. -* | +*) func_quote_arg pretty "$arg" arg=$func_quote_arg_result ;; *.$objext) # A standard object. func_append objs " $arg" ;; *.lo) # A libtool-controlled object. # Check to see that this really is a libtool object. if func_lalib_unsafe_p "$arg"; then pic_object= non_pic_object= # Read the .lo file func_source "$arg" if test -z "$pic_object" || test -z "$non_pic_object" || test none = "$pic_object" && test none = "$non_pic_object"; then func_fatal_error "cannot find name of object for '$arg'" fi # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir=$func_dirname_result test none = "$pic_object" || { # Prepend the subdirectory the object is found in. pic_object=$xdir$pic_object if test dlfiles = "$prev"; then if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then func_append dlfiles " $pic_object" prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi # CHECK ME: I think I busted this. -Ossama if test dlprefiles = "$prev"; then # Preload the old-style object. func_append dlprefiles " $pic_object" prev= fi # A PIC object. func_append libobjs " $pic_object" arg=$pic_object } # Non-PIC object. if test none != "$non_pic_object"; then # Prepend the subdirectory the object is found in. non_pic_object=$xdir$non_pic_object # A standard non-PIC object func_append non_pic_objects " $non_pic_object" if test -z "$pic_object" || test none = "$pic_object"; then arg=$non_pic_object fi else # If the PIC object exists, use it instead. # $xdir was prepended to $pic_object above. non_pic_object=$pic_object func_append non_pic_objects " $non_pic_object" fi else # Only an error if not doing a dry-run. if $opt_dry_run; then # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir=$func_dirname_result func_lo2o "$arg" pic_object=$xdir$objdir/$func_lo2o_result non_pic_object=$xdir$func_lo2o_result func_append libobjs " $pic_object" func_append non_pic_objects " $non_pic_object" else func_fatal_error "'$arg' is not a valid libtool object" fi fi ;; *.$libext) # An archive. func_append deplibs " $arg" func_append old_deplibs " $arg" continue ;; *.la) # A libtool-controlled library. func_resolve_sysroot "$arg" if test dlfiles = "$prev"; then # This library was specified with -dlopen. func_append dlfiles " $func_resolve_sysroot_result" prev= elif test dlprefiles = "$prev"; then # The library was specified with -dlpreopen. func_append dlprefiles " $func_resolve_sysroot_result" prev= else func_append deplibs " $func_resolve_sysroot_result" fi continue ;; # Some other compiler argument. *) # Unknown arguments in both finalize_command and compile_command need # to be aesthetically quoted because they are evaled later. func_quote_arg pretty "$arg" arg=$func_quote_arg_result ;; esac # arg # Now actually substitute the argument into the commands. if test -n "$arg"; then func_append compile_command " $arg" func_append finalize_command " $arg" fi done # argument parsing loop test -n "$prev" && \ func_fatal_help "the '$prevarg' option requires an argument" if test yes = "$export_dynamic" && test -n "$export_dynamic_flag_spec"; then eval arg=\"$export_dynamic_flag_spec\" func_append compile_command " $arg" func_append finalize_command " $arg" fi oldlibs= # calculate the name of the file, without its directory func_basename "$output" outputname=$func_basename_result libobjs_save=$libobjs if test -n "$shlibpath_var"; then # get the directories listed in $shlibpath_var eval shlib_search_path=\`\$ECHO \"\$$shlibpath_var\" \| \$SED \'s/:/ /g\'\` else shlib_search_path= fi eval sys_lib_search_path=\"$sys_lib_search_path_spec\" eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" # Definition is injected by LT_CONFIG during libtool generation. func_munge_path_list sys_lib_dlsearch_path "$LT_SYS_LIBRARY_PATH" func_dirname "$output" "/" "" output_objdir=$func_dirname_result$objdir func_to_tool_file "$output_objdir/" tool_output_objdir=$func_to_tool_file_result # Create the object directory. func_mkdir_p "$output_objdir" # Determine the type of output case $output in "") func_fatal_help "you must specify an output file" ;; *.$libext) linkmode=oldlib ;; *.lo | *.$objext) linkmode=obj ;; *.la) linkmode=lib ;; *) linkmode=prog ;; # Anything else should be a program. esac specialdeplibs= libs= # Find all interdependent deplibs by searching for libraries # that are linked more than once (e.g. -la -lb -la) for deplib in $deplibs; do if $opt_preserve_dup_deps; then case "$libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append libs " $deplib" done if test lib = "$linkmode"; then libs="$predeps $libs $compiler_lib_search_path $postdeps" # Compute libraries that are listed more than once in $predeps # $postdeps and mark them as special (i.e., whose duplicates are # not to be eliminated). pre_post_deps= if $opt_duplicate_compiler_generated_deps; then for pre_post_dep in $predeps $postdeps; do case "$pre_post_deps " in *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;; esac func_append pre_post_deps " $pre_post_dep" done fi pre_post_deps= fi deplibs= newdependency_libs= newlib_search_path= need_relink=no # whether we're linking any uninstalled libtool libraries notinst_deplibs= # not-installed libtool libraries notinst_path= # paths that contain not-installed libtool libraries case $linkmode in lib) passes="conv dlpreopen link" for file in $dlfiles $dlprefiles; do case $file in *.la) ;; *) func_fatal_help "libraries can '-dlopen' only libtool libraries: $file" ;; esac done ;; prog) compile_deplibs= finalize_deplibs= alldeplibs=false newdlfiles= newdlprefiles= passes="conv scan dlopen dlpreopen link" ;; *) passes="conv" ;; esac for pass in $passes; do # The preopen pass in lib mode reverses $deplibs; put it back here # so that -L comes before libs that need it for instance... if test lib,link = "$linkmode,$pass"; then ## FIXME: Find the place where the list is rebuilt in the wrong ## order, and fix it there properly tmp_deplibs= for deplib in $deplibs; do tmp_deplibs="$deplib $tmp_deplibs" done deplibs=$tmp_deplibs fi if test lib,link = "$linkmode,$pass" || test prog,scan = "$linkmode,$pass"; then libs=$deplibs deplibs= fi if test prog = "$linkmode"; then case $pass in dlopen) libs=$dlfiles ;; dlpreopen) libs=$dlprefiles ;; link) libs="$deplibs %DEPLIBS%" test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs" ;; esac fi if test lib,dlpreopen = "$linkmode,$pass"; then # Collect and forward deplibs of preopened libtool libs for lib in $dlprefiles; do # Ignore non-libtool-libs dependency_libs= func_resolve_sysroot "$lib" case $lib in *.la) func_source "$func_resolve_sysroot_result" ;; esac # Collect preopened libtool deplibs, except any this library # has declared as weak libs for deplib in $dependency_libs; do func_basename "$deplib" deplib_base=$func_basename_result case " $weak_libs " in *" $deplib_base "*) ;; *) func_append deplibs " $deplib" ;; esac done done libs=$dlprefiles fi if test dlopen = "$pass"; then # Collect dlpreopened libraries save_deplibs=$deplibs deplibs= fi for deplib in $libs; do lib= found=false case $deplib in -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) if test prog,link = "$linkmode,$pass"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else func_append compiler_flags " $deplib" if test lib = "$linkmode"; then case "$new_inherited_linker_flags " in *" $deplib "*) ;; * ) func_append new_inherited_linker_flags " $deplib" ;; esac fi fi continue ;; -l*) if test lib != "$linkmode" && test prog != "$linkmode"; then func_warning "'-l' is ignored for archives/objects" continue fi func_stripname '-l' '' "$deplib" name=$func_stripname_result if test lib = "$linkmode"; then searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" else searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" fi for searchdir in $searchdirs; do for search_ext in .la $std_shrext .so .a; do # Search the libtool library lib=$searchdir/lib$name$search_ext if test -f "$lib"; then if test .la = "$search_ext"; then found=: else found=false fi break 2 fi done done if $found; then # deplib is a libtool library # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, # We need to do some special things here, and not later. if test yes = "$allow_libtool_libs_with_static_runtimes"; then case " $predeps $postdeps " in *" $deplib "*) if func_lalib_p "$lib"; then library_names= old_library= func_source "$lib" for l in $old_library $library_names; do ll=$l done if test "X$ll" = "X$old_library"; then # only static version available found=false func_dirname "$lib" "" "." ladir=$func_dirname_result lib=$ladir/$old_library if test prog,link = "$linkmode,$pass"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs" fi continue fi fi ;; *) ;; esac fi else # deplib doesn't seem to be a libtool library if test prog,link = "$linkmode,$pass"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs" fi continue fi ;; # -l *.ltframework) if test prog,link = "$linkmode,$pass"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" if test lib = "$linkmode"; then case "$new_inherited_linker_flags " in *" $deplib "*) ;; * ) func_append new_inherited_linker_flags " $deplib" ;; esac fi fi continue ;; -L*) case $linkmode in lib) deplibs="$deplib $deplibs" test conv = "$pass" && continue newdependency_libs="$deplib $newdependency_libs" func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; prog) if test conv = "$pass"; then deplibs="$deplib $deplibs" continue fi if test scan = "$pass"; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; *) func_warning "'-L' is ignored for archives/objects" ;; esac # linkmode continue ;; # -L -R*) if test link = "$pass"; then func_stripname '-R' '' "$deplib" func_resolve_sysroot "$func_stripname_result" dir=$func_resolve_sysroot_result # Make sure the xrpath contains only unique directories. case "$xrpath " in *" $dir "*) ;; *) func_append xrpath " $dir" ;; esac fi deplibs="$deplib $deplibs" continue ;; *.la) func_resolve_sysroot "$deplib" lib=$func_resolve_sysroot_result ;; *.$libext) if test conv = "$pass"; then deplibs="$deplib $deplibs" continue fi case $linkmode in lib) # Linking convenience modules into shared libraries is allowed, # but linking other static libraries is non-portable. case " $dlpreconveniencelibs " in *" $deplib "*) ;; *) valid_a_lib=false case $deplibs_check_method in match_pattern*) set dummy $deplibs_check_method; shift match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \ | $EGREP "$match_pattern_regex" > /dev/null; then valid_a_lib=: fi ;; pass_all) valid_a_lib=: ;; esac if $valid_a_lib; then echo $ECHO "*** Warning: Linking the shared library $output against the" $ECHO "*** static library $deplib is not portable!" deplibs="$deplib $deplibs" else echo $ECHO "*** Warning: Trying to link with static lib archive $deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because the file extensions .$libext of this argument makes me believe" echo "*** that it is just a static archive that I should not use here." fi ;; esac continue ;; prog) if test link != "$pass"; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi continue ;; esac # linkmode ;; # *.$libext *.lo | *.$objext) if test conv = "$pass"; then deplibs="$deplib $deplibs" elif test prog = "$linkmode"; then if test dlpreopen = "$pass" || test yes != "$dlopen_support" || test no = "$build_libtool_libs"; then # If there is no dlopen support or we're linking statically, # we need to preload. func_append newdlprefiles " $deplib" compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else func_append newdlfiles " $deplib" fi fi continue ;; %DEPLIBS%) alldeplibs=: continue ;; esac # case $deplib $found || test -f "$lib" \ || func_fatal_error "cannot find the library '$lib' or unhandled argument '$deplib'" # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$lib" \ || func_fatal_error "'$lib' is not a valid libtool archive" func_dirname "$lib" "" "." ladir=$func_dirname_result dlname= dlopen= dlpreopen= libdir= library_names= old_library= inherited_linker_flags= # If the library was installed with an old release of libtool, # it will not redefine variables installed, or shouldnotlink installed=yes shouldnotlink=no avoidtemprpath= # Read the .la file func_source "$lib" # Convert "-framework foo" to "foo.ltframework" if test -n "$inherited_linker_flags"; then tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'` for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do case " $new_inherited_linker_flags " in *" $tmp_inherited_linker_flag "*) ;; *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";; esac done fi dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` if test lib,link = "$linkmode,$pass" || test prog,scan = "$linkmode,$pass" || { test prog != "$linkmode" && test lib != "$linkmode"; }; then test -n "$dlopen" && func_append dlfiles " $dlopen" test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen" fi if test conv = "$pass"; then # Only check for convenience libraries deplibs="$lib $deplibs" if test -z "$libdir"; then if test -z "$old_library"; then func_fatal_error "cannot find name of link library for '$lib'" fi # It is a libtool convenience library, so add in its objects. func_append convenience " $ladir/$objdir/$old_library" func_append old_convenience " $ladir/$objdir/$old_library" tmp_libs= for deplib in $dependency_libs; do deplibs="$deplib $deplibs" if $opt_preserve_dup_deps; then case "$tmp_libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append tmp_libs " $deplib" done elif test prog != "$linkmode" && test lib != "$linkmode"; then func_fatal_error "'$lib' is not a convenience library" fi continue fi # $pass = conv # Get the name of the library we link against. linklib= if test -n "$old_library" && { test yes = "$prefer_static_libs" || test built,no = "$prefer_static_libs,$installed"; }; then linklib=$old_library else for l in $old_library $library_names; do linklib=$l done fi if test -z "$linklib"; then func_fatal_error "cannot find name of link library for '$lib'" fi # This library was specified with -dlopen. if test dlopen = "$pass"; then test -z "$libdir" \ && func_fatal_error "cannot -dlopen a convenience library: '$lib'" if test -z "$dlname" || test yes != "$dlopen_support" || test no = "$build_libtool_libs" then # If there is no dlname, no dlopen support or we're linking # statically, we need to preload. We also need to preload any # dependent libraries so libltdl's deplib preloader doesn't # bomb out in the load deplibs phase. func_append dlprefiles " $lib $dependency_libs" else func_append newdlfiles " $lib" fi continue fi # $pass = dlopen # We need an absolute path. case $ladir in [\\/]* | [A-Za-z]:[\\/]*) abs_ladir=$ladir ;; *) abs_ladir=`cd "$ladir" && pwd` if test -z "$abs_ladir"; then func_warning "cannot determine absolute directory name of '$ladir'" func_warning "passing it literally to the linker, although it might fail" abs_ladir=$ladir fi ;; esac func_basename "$lib" laname=$func_basename_result # Find the relevant object directory and library name. if test yes = "$installed"; then if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then func_warning "library '$lib' was moved." dir=$ladir absdir=$abs_ladir libdir=$abs_ladir else dir=$lt_sysroot$libdir absdir=$lt_sysroot$libdir fi test yes = "$hardcode_automatic" && avoidtemprpath=yes else if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then dir=$ladir absdir=$abs_ladir # Remove this search path later func_append notinst_path " $abs_ladir" else dir=$ladir/$objdir absdir=$abs_ladir/$objdir # Remove this search path later func_append notinst_path " $abs_ladir" fi fi # $installed = yes func_stripname 'lib' '.la' "$laname" name=$func_stripname_result # This library was specified with -dlpreopen. if test dlpreopen = "$pass"; then if test -z "$libdir" && test prog = "$linkmode"; then func_fatal_error "only libraries may -dlpreopen a convenience library: '$lib'" fi case $host in # special handling for platforms with PE-DLLs. *cygwin* | *mingw* | *cegcc* ) # Linker will automatically link against shared library if both # static and shared are present. Therefore, ensure we extract # symbols from the import library if a shared library is present # (otherwise, the dlopen module name will be incorrect). We do # this by putting the import library name into $newdlprefiles. # We recover the dlopen module name by 'saving' the la file # name in a special purpose variable, and (later) extracting the # dlname from the la file. if test -n "$dlname"; then func_tr_sh "$dir/$linklib" eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname" func_append newdlprefiles " $dir/$linklib" else func_append newdlprefiles " $dir/$old_library" # Keep a list of preopened convenience libraries to check # that they are being used correctly in the link pass. test -z "$libdir" && \ func_append dlpreconveniencelibs " $dir/$old_library" fi ;; * ) # Prefer using a static library (so that no silly _DYNAMIC symbols # are required to link). if test -n "$old_library"; then func_append newdlprefiles " $dir/$old_library" # Keep a list of preopened convenience libraries to check # that they are being used correctly in the link pass. test -z "$libdir" && \ func_append dlpreconveniencelibs " $dir/$old_library" # Otherwise, use the dlname, so that lt_dlopen finds it. elif test -n "$dlname"; then func_append newdlprefiles " $dir/$dlname" else func_append newdlprefiles " $dir/$linklib" fi ;; esac fi # $pass = dlpreopen if test -z "$libdir"; then # Link the convenience library if test lib = "$linkmode"; then deplibs="$dir/$old_library $deplibs" elif test prog,link = "$linkmode,$pass"; then compile_deplibs="$dir/$old_library $compile_deplibs" finalize_deplibs="$dir/$old_library $finalize_deplibs" else deplibs="$lib $deplibs" # used for prog,scan pass fi continue fi if test prog = "$linkmode" && test link != "$pass"; then func_append newlib_search_path " $ladir" deplibs="$lib $deplibs" linkalldeplibs=false if test no != "$link_all_deplibs" || test -z "$library_names" || test no = "$build_libtool_libs"; then linkalldeplibs=: fi tmp_libs= for deplib in $dependency_libs; do case $deplib in -L*) func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; esac # Need to link against all dependency_libs? if $linkalldeplibs; then deplibs="$deplib $deplibs" else # Need to hardcode shared library paths # or/and link against static libraries newdependency_libs="$deplib $newdependency_libs" fi if $opt_preserve_dup_deps; then case "$tmp_libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append tmp_libs " $deplib" done # for deplib continue fi # $linkmode = prog... if test prog,link = "$linkmode,$pass"; then if test -n "$library_names" && { { test no = "$prefer_static_libs" || test built,yes = "$prefer_static_libs,$installed"; } || test -z "$old_library"; }; then # We need to hardcode the library path if test -n "$shlibpath_var" && test -z "$avoidtemprpath"; then # Make sure the rpath contains only unique directories. case $temp_rpath: in *"$absdir:"*) ;; *) func_append temp_rpath "$absdir:" ;; esac fi # Hardcode the library path. # Skip directories that are in the system default run-time # search path. case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) case "$compile_rpath " in *" $absdir "*) ;; *) func_append compile_rpath " $absdir" ;; esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac ;; esac fi # $linkmode,$pass = prog,link... if $alldeplibs && { test pass_all = "$deplibs_check_method" || { test yes = "$build_libtool_libs" && test -n "$library_names"; }; }; then # We only need to search for static libraries continue fi fi link_static=no # Whether the deplib will be linked statically use_static_libs=$prefer_static_libs if test built = "$use_static_libs" && test yes = "$installed"; then use_static_libs=no fi if test -n "$library_names" && { test no = "$use_static_libs" || test -z "$old_library"; }; then case $host in *cygwin* | *mingw* | *cegcc* | *os2*) # No point in relinking DLLs because paths are not encoded func_append notinst_deplibs " $lib" need_relink=no ;; *) if test no = "$installed"; then func_append notinst_deplibs " $lib" need_relink=yes fi ;; esac # This is a shared library # Warn about portability, can't link against -module's on some # systems (darwin). Don't bleat about dlopened modules though! dlopenmodule= for dlpremoduletest in $dlprefiles; do if test "X$dlpremoduletest" = "X$lib"; then dlopenmodule=$dlpremoduletest break fi done if test -z "$dlopenmodule" && test yes = "$shouldnotlink" && test link = "$pass"; then echo if test prog = "$linkmode"; then $ECHO "*** Warning: Linking the executable $output against the loadable module" else $ECHO "*** Warning: Linking the shared library $output against the loadable module" fi $ECHO "*** $linklib is not portable!" fi if test lib = "$linkmode" && test yes = "$hardcode_into_libs"; then # Hardcode the library path. # Skip directories that are in the system default run-time # search path. case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) case "$compile_rpath " in *" $absdir "*) ;; *) func_append compile_rpath " $absdir" ;; esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac ;; esac fi if test -n "$old_archive_from_expsyms_cmds"; then # figure out the soname set dummy $library_names shift realname=$1 shift libname=`eval "\\$ECHO \"$libname_spec\""` # use dlname if we got it. it's perfectly good, no? if test -n "$dlname"; then soname=$dlname elif test -n "$soname_spec"; then # bleh windows case $host in *cygwin* | mingw* | *cegcc* | *os2*) func_arith $current - $age major=$func_arith_result versuffix=-$major ;; esac eval soname=\"$soname_spec\" else soname=$realname fi # Make a new name for the extract_expsyms_cmds to use soroot=$soname func_basename "$soroot" soname=$func_basename_result func_stripname 'lib' '.dll' "$soname" newlib=libimp-$func_stripname_result.a # If the library has no export list, then create one now if test -f "$output_objdir/$soname-def"; then : else func_verbose "extracting exported symbol list from '$soname'" func_execute_cmds "$extract_expsyms_cmds" 'exit $?' fi # Create $newlib if test -f "$output_objdir/$newlib"; then :; else func_verbose "generating import library for '$soname'" func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' fi # make sure the library variables are pointing to the new library dir=$output_objdir linklib=$newlib fi # test -n "$old_archive_from_expsyms_cmds" if test prog = "$linkmode" || test relink != "$opt_mode"; then add_shlibpath= add_dir= add= lib_linked=yes case $hardcode_action in immediate | unsupported) if test no = "$hardcode_direct"; then add=$dir/$linklib case $host in *-*-sco3.2v5.0.[024]*) add_dir=-L$dir ;; *-*-sysv4*uw2*) add_dir=-L$dir ;; *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ *-*-unixware7*) add_dir=-L$dir ;; *-*-darwin* ) # if the lib is a (non-dlopened) module then we cannot # link against it, someone is ignoring the earlier warnings if /usr/bin/file -L $add 2> /dev/null | $GREP ": [^:]* bundle" >/dev/null; then if test "X$dlopenmodule" != "X$lib"; then $ECHO "*** Warning: lib $linklib is a module, not a shared library" if test -z "$old_library"; then echo echo "*** And there doesn't seem to be a static archive available" echo "*** The link will probably fail, sorry" else add=$dir/$old_library fi elif test -n "$old_library"; then add=$dir/$old_library fi fi esac elif test no = "$hardcode_minus_L"; then case $host in *-*-sunos*) add_shlibpath=$dir ;; esac add_dir=-L$dir add=-l$name elif test no = "$hardcode_shlibpath_var"; then add_shlibpath=$dir add=-l$name else lib_linked=no fi ;; relink) if test yes = "$hardcode_direct" && test no = "$hardcode_direct_absolute"; then add=$dir/$linklib elif test yes = "$hardcode_minus_L"; then add_dir=-L$absdir # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in [\\/]*) func_append add_dir " -L$inst_prefix_dir$libdir" ;; esac fi add=-l$name elif test yes = "$hardcode_shlibpath_var"; then add_shlibpath=$dir add=-l$name else lib_linked=no fi ;; *) lib_linked=no ;; esac if test yes != "$lib_linked"; then func_fatal_configuration "unsupported hardcode properties" fi if test -n "$add_shlibpath"; then case :$compile_shlibpath: in *":$add_shlibpath:"*) ;; *) func_append compile_shlibpath "$add_shlibpath:" ;; esac fi if test prog = "$linkmode"; then test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" test -n "$add" && compile_deplibs="$add $compile_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" if test yes != "$hardcode_direct" && test yes != "$hardcode_minus_L" && test yes = "$hardcode_shlibpath_var"; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) func_append finalize_shlibpath "$libdir:" ;; esac fi fi fi if test prog = "$linkmode" || test relink = "$opt_mode"; then add_shlibpath= add_dir= add= # Finalize command for both is simple: just hardcode it. if test yes = "$hardcode_direct" && test no = "$hardcode_direct_absolute"; then add=$libdir/$linklib elif test yes = "$hardcode_minus_L"; then add_dir=-L$libdir add=-l$name elif test yes = "$hardcode_shlibpath_var"; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) func_append finalize_shlibpath "$libdir:" ;; esac add=-l$name elif test yes = "$hardcode_automatic"; then if test -n "$inst_prefix_dir" && test -f "$inst_prefix_dir$libdir/$linklib"; then add=$inst_prefix_dir$libdir/$linklib else add=$libdir/$linklib fi else # We cannot seem to hardcode it, guess we'll fake it. add_dir=-L$libdir # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in [\\/]*) func_append add_dir " -L$inst_prefix_dir$libdir" ;; esac fi add=-l$name fi if test prog = "$linkmode"; then test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" test -n "$add" && finalize_deplibs="$add $finalize_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" fi fi elif test prog = "$linkmode"; then # Here we assume that one of hardcode_direct or hardcode_minus_L # is not unsupported. This is valid on all known static and # shared platforms. if test unsupported != "$hardcode_direct"; then test -n "$old_library" && linklib=$old_library compile_deplibs="$dir/$linklib $compile_deplibs" finalize_deplibs="$dir/$linklib $finalize_deplibs" else compile_deplibs="-l$name -L$dir $compile_deplibs" finalize_deplibs="-l$name -L$dir $finalize_deplibs" fi elif test yes = "$build_libtool_libs"; then # Not a shared library if test pass_all != "$deplibs_check_method"; then # We're trying link a shared library against a static one # but the system doesn't support it. # Just print a warning and add the library to dependency_libs so # that the program can be linked against the static library. echo $ECHO "*** Warning: This system cannot link to static lib archive $lib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have." if test yes = "$module"; then echo "*** But as you try to build a module library, libtool will still create " echo "*** a static module, that should work as long as the dlopening application" echo "*** is linked with the -dlopen flag to resolve symbols at runtime." if test -z "$global_symbol_pipe"; then echo echo "*** However, this would only work if libtool was able to extract symbol" echo "*** lists from a program, using 'nm' or equivalent, but libtool could" echo "*** not find such a program. So, this module is probably useless." echo "*** 'nm' from GNU binutils and a full rebuild may help." fi if test no = "$build_old_libs"; then build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi fi else deplibs="$dir/$old_library $deplibs" link_static=yes fi fi # link shared/static library? if test lib = "$linkmode"; then if test -n "$dependency_libs" && { test yes != "$hardcode_into_libs" || test yes = "$build_old_libs" || test yes = "$link_static"; }; then # Extract -R from dependency_libs temp_deplibs= for libdir in $dependency_libs; do case $libdir in -R*) func_stripname '-R' '' "$libdir" temp_xrpath=$func_stripname_result case " $xrpath " in *" $temp_xrpath "*) ;; *) func_append xrpath " $temp_xrpath";; esac;; *) func_append temp_deplibs " $libdir";; esac done dependency_libs=$temp_deplibs fi func_append newlib_search_path " $absdir" # Link against this library test no = "$link_static" && newdependency_libs="$abs_ladir/$laname $newdependency_libs" # ... and its dependency_libs tmp_libs= for deplib in $dependency_libs; do newdependency_libs="$deplib $newdependency_libs" case $deplib in -L*) func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result";; *) func_resolve_sysroot "$deplib" ;; esac if $opt_preserve_dup_deps; then case "$tmp_libs " in *" $func_resolve_sysroot_result "*) func_append specialdeplibs " $func_resolve_sysroot_result" ;; esac fi func_append tmp_libs " $func_resolve_sysroot_result" done if test no != "$link_all_deplibs"; then # Add the search paths of all dependency libraries for deplib in $dependency_libs; do path= case $deplib in -L*) path=$deplib ;; *.la) func_resolve_sysroot "$deplib" deplib=$func_resolve_sysroot_result func_dirname "$deplib" "" "." dir=$func_dirname_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) absdir=$dir ;; *) absdir=`cd "$dir" && pwd` if test -z "$absdir"; then func_warning "cannot determine absolute directory name of '$dir'" absdir=$dir fi ;; esac if $GREP "^installed=no" $deplib > /dev/null; then case $host in *-*-darwin*) depdepl= eval deplibrary_names=`$SED -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` if test -n "$deplibrary_names"; then for tmp in $deplibrary_names; do depdepl=$tmp done if test -f "$absdir/$objdir/$depdepl"; then depdepl=$absdir/$objdir/$depdepl darwin_install_name=`$OTOOL -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` if test -z "$darwin_install_name"; then darwin_install_name=`$OTOOL64 -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` fi func_append compiler_flags " $wl-dylib_file $wl$darwin_install_name:$depdepl" func_append linker_flags " -dylib_file $darwin_install_name:$depdepl" path= fi fi ;; *) path=-L$absdir/$objdir ;; esac else eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` test -z "$libdir" && \ func_fatal_error "'$deplib' is not a valid libtool archive" test "$absdir" != "$libdir" && \ func_warning "'$deplib' seems to be moved" path=-L$absdir fi ;; esac case " $deplibs " in *" $path "*) ;; *) deplibs="$path $deplibs" ;; esac done fi # link_all_deplibs != no fi # linkmode = lib done # for deplib in $libs if test link = "$pass"; then if test prog = "$linkmode"; then compile_deplibs="$new_inherited_linker_flags $compile_deplibs" finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" else compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` fi fi dependency_libs=$newdependency_libs if test dlpreopen = "$pass"; then # Link the dlpreopened libraries before other libraries for deplib in $save_deplibs; do deplibs="$deplib $deplibs" done fi if test dlopen != "$pass"; then test conv = "$pass" || { # Make sure lib_search_path contains only unique directories. lib_search_path= for dir in $newlib_search_path; do case "$lib_search_path " in *" $dir "*) ;; *) func_append lib_search_path " $dir" ;; esac done newlib_search_path= } if test prog,link = "$linkmode,$pass"; then vars="compile_deplibs finalize_deplibs" else vars=deplibs fi for var in $vars dependency_libs; do # Add libraries to $var in reverse order eval tmp_libs=\"\$$var\" new_libs= for deplib in $tmp_libs; do # FIXME: Pedantically, this is the right thing to do, so # that some nasty dependency loop isn't accidentally # broken: #new_libs="$deplib $new_libs" # Pragmatically, this seems to cause very few problems in # practice: case $deplib in -L*) new_libs="$deplib $new_libs" ;; -R*) ;; *) # And here is the reason: when a library appears more # than once as an explicit dependence of a library, or # is implicitly linked in more than once by the # compiler, it is considered special, and multiple # occurrences thereof are not removed. Compare this # with having the same library being listed as a # dependency of multiple other libraries: in this case, # we know (pedantically, we assume) the library does not # need to be listed more than once, so we keep only the # last copy. This is not always right, but it is rare # enough that we require users that really mean to play # such unportable linking tricks to link the library # using -Wl,-lname, so that libtool does not consider it # for duplicate removal. case " $specialdeplibs " in *" $deplib "*) new_libs="$deplib $new_libs" ;; *) case " $new_libs " in *" $deplib "*) ;; *) new_libs="$deplib $new_libs" ;; esac ;; esac ;; esac done tmp_libs= for deplib in $new_libs; do case $deplib in -L*) case " $tmp_libs " in *" $deplib "*) ;; *) func_append tmp_libs " $deplib" ;; esac ;; *) func_append tmp_libs " $deplib" ;; esac done eval $var=\"$tmp_libs\" done # for var fi # Add Sun CC postdeps if required: test CXX = "$tagname" && { case $host_os in linux*) case `$CC -V 2>&1 | $SED 5q` in *Sun\ C*) # Sun C++ 5.9 func_suncc_cstd_abi if test no != "$suncc_use_cstd_abi"; then func_append postdeps ' -library=Cstd -library=Crun' fi ;; esac ;; solaris*) func_cc_basename "$CC" case $func_cc_basename_result in CC* | sunCC*) func_suncc_cstd_abi if test no != "$suncc_use_cstd_abi"; then func_append postdeps ' -library=Cstd -library=Crun' fi ;; esac ;; esac } # Last step: remove runtime libs from dependency_libs # (they stay in deplibs) tmp_libs= for i in $dependency_libs; do case " $predeps $postdeps $compiler_lib_search_path " in *" $i "*) i= ;; esac if test -n "$i"; then func_append tmp_libs " $i" fi done dependency_libs=$tmp_libs done # for pass if test prog = "$linkmode"; then dlfiles=$newdlfiles fi if test prog = "$linkmode" || test lib = "$linkmode"; then dlprefiles=$newdlprefiles fi case $linkmode in oldlib) if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then func_warning "'-dlopen' is ignored for archives" fi case " $deplibs" in *\ -l* | *\ -L*) func_warning "'-l' and '-L' are ignored for archives" ;; esac test -n "$rpath" && \ func_warning "'-rpath' is ignored for archives" test -n "$xrpath" && \ func_warning "'-R' is ignored for archives" test -n "$vinfo" && \ func_warning "'-version-info/-version-number' is ignored for archives" test -n "$release" && \ func_warning "'-release' is ignored for archives" test -n "$export_symbols$export_symbols_regex" && \ func_warning "'-export-symbols' is ignored for archives" # Now set the variables for building old libraries. build_libtool_libs=no oldlibs=$output func_append objs "$old_deplibs" ;; lib) # Make sure we only generate libraries of the form 'libNAME.la'. case $outputname in lib*) func_stripname 'lib' '.la' "$outputname" name=$func_stripname_result eval shared_ext=\"$shrext_cmds\" eval libname=\"$libname_spec\" ;; *) test no = "$module" \ && func_fatal_help "libtool library '$output' must begin with 'lib'" if test no != "$need_lib_prefix"; then # Add the "lib" prefix for modules if required func_stripname '' '.la' "$outputname" name=$func_stripname_result eval shared_ext=\"$shrext_cmds\" eval libname=\"$libname_spec\" else func_stripname '' '.la' "$outputname" libname=$func_stripname_result fi ;; esac if test -n "$objs"; then if test pass_all != "$deplibs_check_method"; then func_fatal_error "cannot build libtool library '$output' from non-libtool objects on this host:$objs" else echo $ECHO "*** Warning: Linking the shared library $output against the non-libtool" $ECHO "*** objects $objs is not portable!" func_append libobjs " $objs" fi fi test no = "$dlself" \ || func_warning "'-dlopen self' is ignored for libtool libraries" set dummy $rpath shift test 1 -lt "$#" \ && func_warning "ignoring multiple '-rpath's for a libtool library" install_libdir=$1 oldlibs= if test -z "$rpath"; then if test yes = "$build_libtool_libs"; then # Building a libtool convenience library. # Some compilers have problems with a '.al' extension so # convenience libraries should have the same extension an # archive normally would. oldlibs="$output_objdir/$libname.$libext $oldlibs" build_libtool_libs=convenience build_old_libs=yes fi test -n "$vinfo" && \ func_warning "'-version-info/-version-number' is ignored for convenience libraries" test -n "$release" && \ func_warning "'-release' is ignored for convenience libraries" else # Parse the version information argument. save_ifs=$IFS; IFS=: set dummy $vinfo 0 0 0 shift IFS=$save_ifs test -n "$7" && \ func_fatal_help "too many parameters to '-version-info'" # convert absolute version numbers to libtool ages # this retains compatibility with .la files and attempts # to make the code below a bit more comprehensible case $vinfo_number in yes) number_major=$1 number_minor=$2 number_revision=$3 # # There are really only two kinds -- those that # use the current revision as the major version # and those that subtract age and use age as # a minor version. But, then there is irix # that has an extra 1 added just for fun # case $version_type in # correct linux to gnu/linux during the next big refactor darwin|freebsd-elf|linux|midnightbsd-elf|osf|windows|none) func_arith $number_major + $number_minor current=$func_arith_result age=$number_minor revision=$number_revision ;; freebsd-aout|qnx|sunos) current=$number_major revision=$number_minor age=0 ;; irix|nonstopux) func_arith $number_major + $number_minor current=$func_arith_result age=$number_minor revision=$number_minor lt_irix_increment=no ;; *) func_fatal_configuration "$modename: unknown library version type '$version_type'" ;; esac ;; no) current=$1 revision=$2 age=$3 ;; esac # Check that each of the things are valid numbers. case $current in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "CURRENT '$current' must be a nonnegative integer" func_fatal_error "'$vinfo' is not valid version information" ;; esac case $revision in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "REVISION '$revision' must be a nonnegative integer" func_fatal_error "'$vinfo' is not valid version information" ;; esac case $age in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "AGE '$age' must be a nonnegative integer" func_fatal_error "'$vinfo' is not valid version information" ;; esac if test "$age" -gt "$current"; then func_error "AGE '$age' is greater than the current interface number '$current'" func_fatal_error "'$vinfo' is not valid version information" fi # Calculate the version variables. major= versuffix= verstring= case $version_type in none) ;; darwin) # Like Linux, but with the current version available in # verstring for coding it into the library header func_arith $current - $age major=.$func_arith_result versuffix=$major.$age.$revision # Darwin ld doesn't like 0 for these options... func_arith $current + 1 minor_current=$func_arith_result xlcverstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision" verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" # On Darwin other compilers case $CC in nagfor*) verstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision" ;; *) verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" ;; esac ;; freebsd-aout) major=.$current versuffix=.$current.$revision ;; freebsd-elf | midnightbsd-elf) func_arith $current - $age major=.$func_arith_result versuffix=$major.$age.$revision ;; irix | nonstopux) if test no = "$lt_irix_increment"; then func_arith $current - $age else func_arith $current - $age + 1 fi major=$func_arith_result case $version_type in nonstopux) verstring_prefix=nonstopux ;; *) verstring_prefix=sgi ;; esac verstring=$verstring_prefix$major.$revision # Add in all the interfaces that we are compatible with. loop=$revision while test 0 -ne "$loop"; do func_arith $revision - $loop iface=$func_arith_result func_arith $loop - 1 loop=$func_arith_result verstring=$verstring_prefix$major.$iface:$verstring done # Before this point, $major must not contain '.'. major=.$major versuffix=$major.$revision ;; linux) # correct to gnu/linux during the next big refactor func_arith $current - $age major=.$func_arith_result versuffix=$major.$age.$revision ;; osf) func_arith $current - $age major=.$func_arith_result versuffix=.$current.$age.$revision verstring=$current.$age.$revision # Add in all the interfaces that we are compatible with. loop=$age while test 0 -ne "$loop"; do func_arith $current - $loop iface=$func_arith_result func_arith $loop - 1 loop=$func_arith_result verstring=$verstring:$iface.0 done # Make executables depend on our current version. func_append verstring ":$current.0" ;; qnx) major=.$current versuffix=.$current ;; sco) major=.$current versuffix=.$current ;; sunos) major=.$current versuffix=.$current.$revision ;; windows) # Use '-' rather than '.', since we only want one # extension on DOS 8.3 file systems. func_arith $current - $age major=$func_arith_result versuffix=-$major ;; *) func_fatal_configuration "unknown library version type '$version_type'" ;; esac # Clear the version info if we defaulted, and they specified a release. if test -z "$vinfo" && test -n "$release"; then major= case $version_type in darwin) # we can't check for "0.0" in archive_cmds due to quoting # problems, so we reset it completely verstring= ;; *) verstring=0.0 ;; esac if test no = "$need_version"; then versuffix= else versuffix=.0.0 fi fi # Remove version info from name if versioning should be avoided if test yes,no = "$avoid_version,$need_version"; then major= versuffix= verstring= fi # Check to see if the archive will have undefined symbols. if test yes = "$allow_undefined"; then if test unsupported = "$allow_undefined_flag"; then if test yes = "$build_old_libs"; then func_warning "undefined symbols not allowed in $host shared libraries; building static only" build_libtool_libs=no else func_fatal_error "can't build $host shared library unless -no-undefined is specified" fi fi else # Don't allow undefined symbols. allow_undefined_flag=$no_undefined_flag fi fi func_generate_dlsyms "$libname" "$libname" : func_append libobjs " $symfileobj" test " " = "$libobjs" && libobjs= if test relink != "$opt_mode"; then # Remove our outputs, but don't remove object files since they # may have been created when compiling PIC objects. removelist= tempremovelist=`$ECHO "$output_objdir/*"` for p in $tempremovelist; do case $p in *.$objext | *.gcno) ;; $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/$libname$release.*) if test -n "$precious_files_regex"; then if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 then continue fi fi func_append removelist " $p" ;; *) ;; esac done test -n "$removelist" && \ func_show_eval "${RM}r \$removelist" fi # Now set the variables for building old libraries. if test yes = "$build_old_libs" && test convenience != "$build_libtool_libs"; then func_append oldlibs " $output_objdir/$libname.$libext" # Transform .lo files to .o files. oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; $lo2o" | $NL2SP` fi # Eliminate all temporary directories. #for path in $notinst_path; do # lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"` # deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"` # dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"` #done if test -n "$xrpath"; then # If the user specified any rpath flags, then add them. temp_xrpath= for libdir in $xrpath; do func_replace_sysroot "$libdir" func_append temp_xrpath " -R$func_replace_sysroot_result" case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac done if test yes != "$hardcode_into_libs" || test yes = "$build_old_libs"; then dependency_libs="$temp_xrpath $dependency_libs" fi fi # Make sure dlfiles contains only unique files that won't be dlpreopened old_dlfiles=$dlfiles dlfiles= for lib in $old_dlfiles; do case " $dlprefiles $dlfiles " in *" $lib "*) ;; *) func_append dlfiles " $lib" ;; esac done # Make sure dlprefiles contains only unique files old_dlprefiles=$dlprefiles dlprefiles= for lib in $old_dlprefiles; do case "$dlprefiles " in *" $lib "*) ;; *) func_append dlprefiles " $lib" ;; esac done if test yes = "$build_libtool_libs"; then if test -n "$rpath"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*) # these systems don't actually have a c library (as such)! ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C library is in the System framework func_append deplibs " System.ltframework" ;; *-*-netbsd*) # Don't link with libc until the a.out ld.so is fixed. ;; *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-midnightbsd*) # Do not include libc due to us having libc/libc_r. ;; *-*-sco3.2v5* | *-*-sco5v6*) # Causes problems with __ctype ;; *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) # Compiler inserts libc in the correct place for threads to work ;; *) # Add libc to deplibs on all other systems if necessary. if test yes = "$build_libtool_need_lc"; then func_append deplibs " -lc" fi ;; esac fi # Transform deplibs into only deplibs that can be linked in shared. name_save=$name libname_save=$libname release_save=$release versuffix_save=$versuffix major_save=$major # I'm not sure if I'm treating the release correctly. I think # release should show up in the -l (ie -lgmp5) so we don't want to # add it in twice. Is that correct? release= versuffix= major= newdeplibs= droppeddeps=no case $deplibs_check_method in pass_all) # Don't check for shared/static. Everything works. # This might be a little naive. We might want to check # whether the library exists or not. But this is on # osf3 & osf4 and I'm not really sure... Just # implementing what was already the behavior. newdeplibs=$deplibs ;; test_compile) # This code stresses the "libraries are programs" paradigm to its # limits. Maybe even breaks it. We compile a program, linking it # against the deplibs as a proxy for the library. Then we can check # whether they linked in statically or dynamically with ldd. $opt_dry_run || $RM conftest.c cat > conftest.c </dev/null` $nocaseglob else potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null` fi for potent_lib in $potential_libs; do # Follow soft links. if ls -lLd "$potent_lib" 2>/dev/null | $GREP " -> " >/dev/null; then continue fi # The statement above tries to avoid entering an # endless loop below, in case of cyclic links. # We might still enter an endless loop, since a link # loop can be closed while we follow links, # but so what? potlib=$potent_lib while test -h "$potlib" 2>/dev/null; do potliblink=`ls -ld $potlib | $SED 's/.* -> //'` case $potliblink in [\\/]* | [A-Za-z]:[\\/]*) potlib=$potliblink;; *) potlib=`$ECHO "$potlib" | $SED 's|[^/]*$||'`"$potliblink";; esac done if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | $SED -e 10q | $EGREP "$file_magic_regex" > /dev/null; then func_append newdeplibs " $a_deplib" a_deplib= break 2 fi done done fi if test -n "$a_deplib"; then droppeddeps=yes echo $ECHO "*** Warning: linker path does not have real file for library $a_deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because I did check the linker path looking for a file starting" if test -z "$potlib"; then $ECHO "*** with $libname but no candidates were found. (...for file magic test)" else $ECHO "*** with $libname and none of the candidates passed a file format test" $ECHO "*** using a file magic. Last file checked: $potlib" fi fi ;; *) # Add a -L argument. func_append newdeplibs " $a_deplib" ;; esac done # Gone through all deplibs. ;; match_pattern*) set dummy $deplibs_check_method; shift match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` for a_deplib in $deplibs; do case $a_deplib in -l*) func_stripname -l '' "$a_deplib" name=$func_stripname_result if test yes = "$allow_libtool_libs_with_static_runtimes"; then case " $predeps $postdeps " in *" $a_deplib "*) func_append newdeplibs " $a_deplib" a_deplib= ;; esac fi if test -n "$a_deplib"; then libname=`eval "\\$ECHO \"$libname_spec\""` for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do potential_libs=`ls $i/$libname[.-]* 2>/dev/null` for potent_lib in $potential_libs; do potlib=$potent_lib # see symlink-check above in file_magic test if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \ $EGREP "$match_pattern_regex" > /dev/null; then func_append newdeplibs " $a_deplib" a_deplib= break 2 fi done done fi if test -n "$a_deplib"; then droppeddeps=yes echo $ECHO "*** Warning: linker path does not have real file for library $a_deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because I did check the linker path looking for a file starting" if test -z "$potlib"; then $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)" else $ECHO "*** with $libname and none of the candidates passed a file format test" $ECHO "*** using a regex pattern. Last file checked: $potlib" fi fi ;; *) # Add a -L argument. func_append newdeplibs " $a_deplib" ;; esac done # Gone through all deplibs. ;; none | unknown | *) newdeplibs= tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'` if test yes = "$allow_libtool_libs_with_static_runtimes"; then for i in $predeps $postdeps; do # can't use Xsed below, because $i might contain '/' tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s|$i||"` done fi case $tmp_deplibs in *[!\ \ ]*) echo if test none = "$deplibs_check_method"; then echo "*** Warning: inter-library dependencies are not supported in this platform." else echo "*** Warning: inter-library dependencies are not known to be supported." fi echo "*** All declared inter-library dependencies are being dropped." droppeddeps=yes ;; esac ;; esac versuffix=$versuffix_save major=$major_save release=$release_save libname=$libname_save name=$name_save case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library with the System framework newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'` ;; esac if test yes = "$droppeddeps"; then if test yes = "$module"; then echo echo "*** Warning: libtool could not satisfy all declared inter-library" $ECHO "*** dependencies of module $libname. Therefore, libtool will create" echo "*** a static module, that should work as long as the dlopening" echo "*** application is linked with the -dlopen flag." if test -z "$global_symbol_pipe"; then echo echo "*** However, this would only work if libtool was able to extract symbol" echo "*** lists from a program, using 'nm' or equivalent, but libtool could" echo "*** not find such a program. So, this module is probably useless." echo "*** 'nm' from GNU binutils and a full rebuild may help." fi if test no = "$build_old_libs"; then oldlibs=$output_objdir/$libname.$libext build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi else echo "*** The inter-library dependencies that have been dropped here will be" echo "*** automatically added whenever a program is linked with this library" echo "*** or is declared to -dlopen it." if test no = "$allow_undefined"; then echo echo "*** Since this library must not contain undefined symbols," echo "*** because either the platform does not support them or" echo "*** it was explicitly requested with -no-undefined," echo "*** libtool will only create a static version of it." if test no = "$build_old_libs"; then oldlibs=$output_objdir/$libname.$libext build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi fi fi fi # Done checking deplibs! deplibs=$newdeplibs fi # Time to change all our "foo.ltframework" stuff back to "-framework foo" case $host in *-*-darwin*) newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` ;; esac # move library search paths that coincide with paths to not yet # installed libraries to the beginning of the library search list new_libs= for path in $notinst_path; do case " $new_libs " in *" -L$path/$objdir "*) ;; *) case " $deplibs " in *" -L$path/$objdir "*) func_append new_libs " -L$path/$objdir" ;; esac ;; esac done for deplib in $deplibs; do case $deplib in -L*) case " $new_libs " in *" $deplib "*) ;; *) func_append new_libs " $deplib" ;; esac ;; *) func_append new_libs " $deplib" ;; esac done deplibs=$new_libs # All the library-specific variables (install_libdir is set above). library_names= old_library= dlname= # Test again, we may have decided not to build it any more if test yes = "$build_libtool_libs"; then # Remove $wl instances when linking with ld. # FIXME: should test the right _cmds variable. case $archive_cmds in *\$LD\ *) wl= ;; esac if test yes = "$hardcode_into_libs"; then # Hardcode the library paths hardcode_libdirs= dep_rpath= rpath=$finalize_rpath test relink = "$opt_mode" || rpath=$compile_rpath$rpath for libdir in $rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then func_replace_sysroot "$libdir" libdir=$func_replace_sysroot_result if test -z "$hardcode_libdirs"; then hardcode_libdirs=$libdir else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append dep_rpath " $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) func_append perm_rpath " $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir=$hardcode_libdirs eval "dep_rpath=\"$hardcode_libdir_flag_spec\"" fi if test -n "$runpath_var" && test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do func_append rpath "$dir:" done eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" fi test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" fi shlibpath=$finalize_shlibpath test relink = "$opt_mode" || shlibpath=$compile_shlibpath$shlibpath if test -n "$shlibpath"; then eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" fi # Get the real and link names of the library. eval shared_ext=\"$shrext_cmds\" eval library_names=\"$library_names_spec\" set dummy $library_names shift realname=$1 shift if test -n "$soname_spec"; then eval soname=\"$soname_spec\" else soname=$realname fi if test -z "$dlname"; then dlname=$soname fi lib=$output_objdir/$realname linknames= for link do func_append linknames " $link" done # Use standard objects if they are pic test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP` test "X$libobjs" = "X " && libobjs= delfiles= if test -n "$export_symbols" && test -n "$include_expsyms"; then $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp" export_symbols=$output_objdir/$libname.uexp func_append delfiles " $export_symbols" fi orig_export_symbols= case $host_os in cygwin* | mingw* | cegcc*) if test -n "$export_symbols" && test -z "$export_symbols_regex"; then # exporting using user supplied symfile func_dll_def_p "$export_symbols" || { # and it's NOT already a .def file. Must figure out # which of the given symbols are data symbols and tag # them as such. So, trigger use of export_symbols_cmds. # export_symbols gets reassigned inside the "prepare # the list of exported symbols" if statement, so the # include_expsyms logic still works. orig_export_symbols=$export_symbols export_symbols= always_export_symbols=yes } fi ;; esac # Prepare the list of exported symbols if test -z "$export_symbols"; then if test yes = "$always_export_symbols" || test -n "$export_symbols_regex"; then func_verbose "generating symbol list for '$libname.la'" export_symbols=$output_objdir/$libname.exp $opt_dry_run || $RM $export_symbols cmds=$export_symbols_cmds save_ifs=$IFS; IFS='~' for cmd1 in $cmds; do IFS=$save_ifs # Take the normal branch if the nm_file_list_spec branch # doesn't work or if tool conversion is not needed. case $nm_file_list_spec~$to_tool_file_cmd in *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*) try_normal_branch=yes eval cmd=\"$cmd1\" func_len " $cmd" len=$func_len_result ;; *) try_normal_branch=no ;; esac if test yes = "$try_normal_branch" \ && { test "$len" -lt "$max_cmd_len" \ || test "$max_cmd_len" -le -1; } then func_show_eval "$cmd" 'exit $?' skipped_export=false elif test -n "$nm_file_list_spec"; then func_basename "$output" output_la=$func_basename_result save_libobjs=$libobjs save_output=$output output=$output_objdir/$output_la.nm func_to_tool_file "$output" libobjs=$nm_file_list_spec$func_to_tool_file_result func_append delfiles " $output" func_verbose "creating $NM input file list: $output" for obj in $save_libobjs; do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" done > "$output" eval cmd=\"$cmd1\" func_show_eval "$cmd" 'exit $?' output=$save_output libobjs=$save_libobjs skipped_export=false else # The command line is too long to execute in one step. func_verbose "using reloadable object file for export list..." skipped_export=: # Break out early, otherwise skipped_export may be # set to false by a later but shorter cmd. break fi done IFS=$save_ifs if test -n "$export_symbols_regex" && test : != "$skipped_export"; then func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' func_show_eval '$MV "${export_symbols}T" "$export_symbols"' fi fi fi if test -n "$export_symbols" && test -n "$include_expsyms"; then tmp_export_symbols=$export_symbols test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' fi if test : != "$skipped_export" && test -n "$orig_export_symbols"; then # The given exports_symbols file has to be filtered, so filter it. func_verbose "filter symbol list for '$libname.la' to tag DATA exports" # FIXME: $output_objdir/$libname.filter potentially contains lots of # 's' commands, which not all seds can handle. GNU sed should be fine # though. Also, the filter scales superlinearly with the number of # global variables. join(1) would be nice here, but unfortunately # isn't a blessed tool. $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter func_append delfiles " $export_symbols $output_objdir/$libname.filter" export_symbols=$output_objdir/$libname.def $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols fi tmp_deplibs= for test_deplib in $deplibs; do case " $convenience " in *" $test_deplib "*) ;; *) func_append tmp_deplibs " $test_deplib" ;; esac done deplibs=$tmp_deplibs if test -n "$convenience"; then if test -n "$whole_archive_flag_spec" && test yes = "$compiler_needs_object" && test -z "$libobjs"; then # extract the archives, so we have objects to list. # TODO: could optimize this to just extract one archive. whole_archive_flag_spec= fi if test -n "$whole_archive_flag_spec"; then save_libobjs=$libobjs eval libobjs=\"\$libobjs $whole_archive_flag_spec\" test "X$libobjs" = "X " && libobjs= else gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_extract_archives $gentop $convenience func_append libobjs " $func_extract_archives_result" test "X$libobjs" = "X " && libobjs= fi fi if test yes = "$thread_safe" && test -n "$thread_safe_flag_spec"; then eval flag=\"$thread_safe_flag_spec\" func_append linker_flags " $flag" fi # Make a backup of the uninstalled library when relinking if test relink = "$opt_mode"; then $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $? fi # Do each of the archive commands. if test yes = "$module" && test -n "$module_cmds"; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then eval test_cmds=\"$module_expsym_cmds\" cmds=$module_expsym_cmds else eval test_cmds=\"$module_cmds\" cmds=$module_cmds fi else if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then eval test_cmds=\"$archive_expsym_cmds\" cmds=$archive_expsym_cmds else eval test_cmds=\"$archive_cmds\" cmds=$archive_cmds fi fi if test : != "$skipped_export" && func_len " $test_cmds" && len=$func_len_result && test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then : else # The command line is too long to link in one step, link piecewise # or, if using GNU ld and skipped_export is not :, use a linker # script. # Save the value of $output and $libobjs because we want to # use them later. If we have whole_archive_flag_spec, we # want to use save_libobjs as it was before # whole_archive_flag_spec was expanded, because we can't # assume the linker understands whole_archive_flag_spec. # This may have to be revisited, in case too many # convenience libraries get linked in and end up exceeding # the spec. if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then save_libobjs=$libobjs fi save_output=$output func_basename "$output" output_la=$func_basename_result # Clear the reloadable object creation command queue and # initialize k to one. test_cmds= concat_cmds= objlist= last_robj= k=1 if test -n "$save_libobjs" && test : != "$skipped_export" && test yes = "$with_gnu_ld"; then output=$output_objdir/$output_la.lnkscript func_verbose "creating GNU ld script: $output" echo 'INPUT (' > $output for obj in $save_libobjs do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" >> $output done echo ')' >> $output func_append delfiles " $output" func_to_tool_file "$output" output=$func_to_tool_file_result elif test -n "$save_libobjs" && test : != "$skipped_export" && test -n "$file_list_spec"; then output=$output_objdir/$output_la.lnk func_verbose "creating linker input file list: $output" : > $output set x $save_libobjs shift firstobj= if test yes = "$compiler_needs_object"; then firstobj="$1 " shift fi for obj do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" >> $output done func_append delfiles " $output" func_to_tool_file "$output" output=$firstobj\"$file_list_spec$func_to_tool_file_result\" else if test -n "$save_libobjs"; then func_verbose "creating reloadable object files..." output=$output_objdir/$output_la-$k.$objext eval test_cmds=\"$reload_cmds\" func_len " $test_cmds" len0=$func_len_result len=$len0 # Loop over the list of objects to be linked. for obj in $save_libobjs do func_len " $obj" func_arith $len + $func_len_result len=$func_arith_result if test -z "$objlist" || test "$len" -lt "$max_cmd_len"; then func_append objlist " $obj" else # The command $test_cmds is almost too long, add a # command to the queue. if test 1 -eq "$k"; then # The first file doesn't have a previous command to add. reload_objs=$objlist eval concat_cmds=\"$reload_cmds\" else # All subsequent reloadable object files will link in # the last one created. reload_objs="$objlist $last_robj" eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\" fi last_robj=$output_objdir/$output_la-$k.$objext func_arith $k + 1 k=$func_arith_result output=$output_objdir/$output_la-$k.$objext objlist=" $obj" func_len " $last_robj" func_arith $len0 + $func_len_result len=$func_arith_result fi done # Handle the remaining objects by creating one last # reloadable object file. All subsequent reloadable object # files will link in the last one created. test -z "$concat_cmds" || concat_cmds=$concat_cmds~ reload_objs="$objlist $last_robj" eval concat_cmds=\"\$concat_cmds$reload_cmds\" if test -n "$last_robj"; then eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" fi func_append delfiles " $output" else output= fi ${skipped_export-false} && { func_verbose "generating symbol list for '$libname.la'" export_symbols=$output_objdir/$libname.exp $opt_dry_run || $RM $export_symbols libobjs=$output # Append the command to create the export file. test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\" if test -n "$last_robj"; then eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" fi } test -n "$save_libobjs" && func_verbose "creating a temporary reloadable object file: $output" # Loop through the commands generated above and execute them. save_ifs=$IFS; IFS='~' for cmd in $concat_cmds; do IFS=$save_ifs $opt_quiet || { func_quote_arg expand,pretty "$cmd" eval "func_echo $func_quote_arg_result" } $opt_dry_run || eval "$cmd" || { lt_exit=$? # Restore the uninstalled library and exit if test relink = "$opt_mode"; then ( cd "$output_objdir" && \ $RM "${realname}T" && \ $MV "${realname}U" "$realname" ) fi exit $lt_exit } done IFS=$save_ifs if test -n "$export_symbols_regex" && ${skipped_export-false}; then func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' func_show_eval '$MV "${export_symbols}T" "$export_symbols"' fi fi ${skipped_export-false} && { if test -n "$export_symbols" && test -n "$include_expsyms"; then tmp_export_symbols=$export_symbols test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' fi if test -n "$orig_export_symbols"; then # The given exports_symbols file has to be filtered, so filter it. func_verbose "filter symbol list for '$libname.la' to tag DATA exports" # FIXME: $output_objdir/$libname.filter potentially contains lots of # 's' commands, which not all seds can handle. GNU sed should be fine # though. Also, the filter scales superlinearly with the number of # global variables. join(1) would be nice here, but unfortunately # isn't a blessed tool. $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter func_append delfiles " $export_symbols $output_objdir/$libname.filter" export_symbols=$output_objdir/$libname.def $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols fi } libobjs=$output # Restore the value of output. output=$save_output if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then eval libobjs=\"\$libobjs $whole_archive_flag_spec\" test "X$libobjs" = "X " && libobjs= fi # Expand the library linking commands again to reset the # value of $libobjs for piecewise linking. # Do each of the archive commands. if test yes = "$module" && test -n "$module_cmds"; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then cmds=$module_expsym_cmds else cmds=$module_cmds fi else if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then cmds=$archive_expsym_cmds else cmds=$archive_cmds fi fi fi if test -n "$delfiles"; then # Append the command to remove temporary files to $cmds. eval cmds=\"\$cmds~\$RM $delfiles\" fi # Add any objects from preloaded convenience libraries if test -n "$dlprefiles"; then gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_extract_archives $gentop $dlprefiles func_append libobjs " $func_extract_archives_result" test "X$libobjs" = "X " && libobjs= fi save_ifs=$IFS; IFS='~' for cmd in $cmds; do IFS=$sp$nl eval cmd=\"$cmd\" IFS=$save_ifs $opt_quiet || { func_quote_arg expand,pretty "$cmd" eval "func_echo $func_quote_arg_result" } $opt_dry_run || eval "$cmd" || { lt_exit=$? # Restore the uninstalled library and exit if test relink = "$opt_mode"; then ( cd "$output_objdir" && \ $RM "${realname}T" && \ $MV "${realname}U" "$realname" ) fi exit $lt_exit } done IFS=$save_ifs # Restore the uninstalled library and exit if test relink = "$opt_mode"; then $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $? if test -n "$convenience"; then if test -z "$whole_archive_flag_spec"; then func_show_eval '${RM}r "$gentop"' fi fi exit $EXIT_SUCCESS fi # Create links to the real library. for linkname in $linknames; do if test "$realname" != "$linkname"; then func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?' fi done # If -module or -export-dynamic was specified, set the dlname. if test yes = "$module" || test yes = "$export_dynamic"; then # On all known operating systems, these are identical. dlname=$soname fi fi ;; obj) if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then func_warning "'-dlopen' is ignored for objects" fi case " $deplibs" in *\ -l* | *\ -L*) func_warning "'-l' and '-L' are ignored for objects" ;; esac test -n "$rpath" && \ func_warning "'-rpath' is ignored for objects" test -n "$xrpath" && \ func_warning "'-R' is ignored for objects" test -n "$vinfo" && \ func_warning "'-version-info' is ignored for objects" test -n "$release" && \ func_warning "'-release' is ignored for objects" case $output in *.lo) test -n "$objs$old_deplibs" && \ func_fatal_error "cannot build library object '$output' from non-libtool objects" libobj=$output func_lo2o "$libobj" obj=$func_lo2o_result ;; *) libobj= obj=$output ;; esac # Delete the old objects. $opt_dry_run || $RM $obj $libobj # Objects from convenience libraries. This assumes # single-version convenience libraries. Whenever we create # different ones for PIC/non-PIC, this we'll have to duplicate # the extraction. reload_conv_objs= gentop= # if reload_cmds runs $LD directly, get rid of -Wl from # whole_archive_flag_spec and hope we can get by with turning comma # into space. case $reload_cmds in *\$LD[\ \$]*) wl= ;; esac if test -n "$convenience"; then if test -n "$whole_archive_flag_spec"; then eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" test -n "$wl" || tmp_whole_archive_flags=`$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'` reload_conv_objs=$reload_objs\ $tmp_whole_archive_flags else gentop=$output_objdir/${obj}x func_append generated " $gentop" func_extract_archives $gentop $convenience reload_conv_objs="$reload_objs $func_extract_archives_result" fi fi # If we're not building shared, we need to use non_pic_objs test yes = "$build_libtool_libs" || libobjs=$non_pic_objects # Create the old-style object. reload_objs=$objs$old_deplibs' '`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; /\.lib$/d; $lo2o" | $NL2SP`' '$reload_conv_objs output=$obj func_execute_cmds "$reload_cmds" 'exit $?' # Exit if we aren't doing a library object file. if test -z "$libobj"; then if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi exit $EXIT_SUCCESS fi test yes = "$build_libtool_libs" || { if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi # Create an invalid libtool object if no PIC, so that we don't # accidentally link it into a program. # $show "echo timestamp > $libobj" # $opt_dry_run || eval "echo timestamp > $libobj" || exit $? exit $EXIT_SUCCESS } if test -n "$pic_flag" || test default != "$pic_mode"; then # Only do commands if we really have different PIC objects. reload_objs="$libobjs $reload_conv_objs" output=$libobj func_execute_cmds "$reload_cmds" 'exit $?' fi if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi exit $EXIT_SUCCESS ;; prog) case $host in *cygwin*) func_stripname '' '.exe' "$output" output=$func_stripname_result.exe;; esac test -n "$vinfo" && \ func_warning "'-version-info' is ignored for programs" test -n "$release" && \ func_warning "'-release' is ignored for programs" $preload \ && test unknown,unknown,unknown = "$dlopen_support,$dlopen_self,$dlopen_self_static" \ && func_warning "'LT_INIT([dlopen])' not used. Assuming no dlopen support." case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library is the System framework compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'` finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'` ;; esac case $host in *-*-darwin*) # Don't allow lazy linking, it breaks C++ global constructors # But is supposedly fixed on 10.4 or later (yay!). if test CXX = "$tagname"; then case ${MACOSX_DEPLOYMENT_TARGET-10.0} in 10.[0123]) func_append compile_command " $wl-bind_at_load" func_append finalize_command " $wl-bind_at_load" ;; esac fi # Time to change all our "foo.ltframework" stuff back to "-framework foo" compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` ;; esac # move library search paths that coincide with paths to not yet # installed libraries to the beginning of the library search list new_libs= for path in $notinst_path; do case " $new_libs " in *" -L$path/$objdir "*) ;; *) case " $compile_deplibs " in *" -L$path/$objdir "*) func_append new_libs " -L$path/$objdir" ;; esac ;; esac done for deplib in $compile_deplibs; do case $deplib in -L*) case " $new_libs " in *" $deplib "*) ;; *) func_append new_libs " $deplib" ;; esac ;; *) func_append new_libs " $deplib" ;; esac done compile_deplibs=$new_libs func_append compile_command " $compile_deplibs" func_append finalize_command " $finalize_deplibs" if test -n "$rpath$xrpath"; then # If the user specified any rpath flags, then add them. for libdir in $rpath $xrpath; do # This is the magic to use -rpath. case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac done fi # Now hardcode the library paths rpath= hardcode_libdirs= for libdir in $compile_rpath $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs=$libdir else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append rpath " $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) func_append perm_rpath " $libdir" ;; esac fi case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) testbindir=`$ECHO "$libdir" | $SED -e 's*/lib$*/bin*'` case :$dllsearchpath: in *":$libdir:"*) ;; ::) dllsearchpath=$libdir;; *) func_append dllsearchpath ":$libdir";; esac case :$dllsearchpath: in *":$testbindir:"*) ;; ::) dllsearchpath=$testbindir;; *) func_append dllsearchpath ":$testbindir";; esac ;; esac done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir=$hardcode_libdirs eval rpath=\" $hardcode_libdir_flag_spec\" fi compile_rpath=$rpath rpath= hardcode_libdirs= for libdir in $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs=$libdir else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append rpath " $flag" fi elif test -n "$runpath_var"; then case "$finalize_perm_rpath " in *" $libdir "*) ;; *) func_append finalize_perm_rpath " $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir=$hardcode_libdirs eval rpath=\" $hardcode_libdir_flag_spec\" fi finalize_rpath=$rpath if test -n "$libobjs" && test yes = "$build_old_libs"; then # Transform all the library objects into standard objects. compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP` finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP` fi func_generate_dlsyms "$outputname" "@PROGRAM@" false # template prelinking step if test -n "$prelink_cmds"; then func_execute_cmds "$prelink_cmds" 'exit $?' fi wrappers_required=: case $host in *cegcc* | *mingw32ce*) # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway. wrappers_required=false ;; *cygwin* | *mingw* ) test yes = "$build_libtool_libs" || wrappers_required=false ;; *) if test no = "$need_relink" || test yes != "$build_libtool_libs"; then wrappers_required=false fi ;; esac $wrappers_required || { # Replace the output file specification. compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'` link_command=$compile_command$compile_rpath # We have no uninstalled library dependencies, so finalize right now. exit_status=0 func_show_eval "$link_command" 'exit_status=$?' if test -n "$postlink_cmds"; then func_to_tool_file "$output" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi # Delete the generated files. if test -f "$output_objdir/${outputname}S.$objext"; then func_show_eval '$RM "$output_objdir/${outputname}S.$objext"' fi exit $exit_status } if test -n "$compile_shlibpath$finalize_shlibpath"; then compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" fi if test -n "$finalize_shlibpath"; then finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" fi compile_var= finalize_var= if test -n "$runpath_var"; then if test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do func_append rpath "$dir:" done compile_var="$runpath_var=\"$rpath\$$runpath_var\" " fi if test -n "$finalize_perm_rpath"; then # We should set the runpath_var. rpath= for dir in $finalize_perm_rpath; do func_append rpath "$dir:" done finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " fi fi if test yes = "$no_install"; then # We don't need to create a wrapper script. link_command=$compile_var$compile_command$compile_rpath # Replace the output file specification. link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'` # Delete the old output file. $opt_dry_run || $RM $output # Link the executable and exit func_show_eval "$link_command" 'exit $?' if test -n "$postlink_cmds"; then func_to_tool_file "$output" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi exit $EXIT_SUCCESS fi case $hardcode_action,$fast_install in relink,*) # Fast installation is not supported link_command=$compile_var$compile_command$compile_rpath relink_command=$finalize_var$finalize_command$finalize_rpath func_warning "this platform does not like uninstalled shared libraries" func_warning "'$output' will be relinked during installation" ;; *,yes) link_command=$finalize_var$compile_command$finalize_rpath relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'` ;; *,no) link_command=$compile_var$compile_command$compile_rpath relink_command=$finalize_var$finalize_command$finalize_rpath ;; *,needless) link_command=$finalize_var$compile_command$finalize_rpath relink_command= ;; esac # Replace the output file specification. link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` # Delete the old output files. $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname func_show_eval "$link_command" 'exit $?' if test -n "$postlink_cmds"; then func_to_tool_file "$output_objdir/$outputname" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi # Now create the wrapper script. func_verbose "creating $output" # Quote the relink command for shipping. if test -n "$relink_command"; then # Preserve any variables that may affect compiler behavior for var in $variables_saved_for_relink; do if eval test -z \"\${$var+set}\"; then relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else func_quote_arg pretty "$var_value" relink_command="$var=$func_quote_arg_result; export $var; $relink_command" fi done func_quote eval cd "`pwd`" func_quote_arg pretty,unquoted "($func_quote_result; $relink_command)" relink_command=$func_quote_arg_unquoted_result fi # Only actually do things if not in dry run mode. $opt_dry_run || { # win32 will think the script is a binary if it has # a .exe suffix, so we strip it off here. case $output in *.exe) func_stripname '' '.exe' "$output" output=$func_stripname_result ;; esac # test for cygwin because mv fails w/o .exe extensions case $host in *cygwin*) exeext=.exe func_stripname '' '.exe' "$outputname" outputname=$func_stripname_result ;; *) exeext= ;; esac case $host in *cygwin* | *mingw* ) func_dirname_and_basename "$output" "" "." output_name=$func_basename_result output_path=$func_dirname_result cwrappersource=$output_path/$objdir/lt-$output_name.c cwrapper=$output_path/$output_name.exe $RM $cwrappersource $cwrapper trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 func_emit_cwrapperexe_src > $cwrappersource # The wrapper executable is built using the $host compiler, # because it contains $host paths and files. If cross- # compiling, it, like the target executable, must be # executed on the $host or under an emulation environment. $opt_dry_run || { $LTCC $LTCFLAGS -o $cwrapper $cwrappersource $STRIP $cwrapper } # Now, create the wrapper script for func_source use: func_ltwrapper_scriptname $cwrapper $RM $func_ltwrapper_scriptname_result trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15 $opt_dry_run || { # note: this script will not be executed, so do not chmod. if test "x$build" = "x$host"; then $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result else func_emit_wrapper no > $func_ltwrapper_scriptname_result fi } ;; * ) $RM $output trap "$RM $output; exit $EXIT_FAILURE" 1 2 15 func_emit_wrapper no > $output chmod +x $output ;; esac } exit $EXIT_SUCCESS ;; esac # See if we need to build an old-fashioned archive. for oldlib in $oldlibs; do case $build_libtool_libs in convenience) oldobjs="$libobjs_save $symfileobj" addlibs=$convenience build_libtool_libs=no ;; module) oldobjs=$libobjs_save addlibs=$old_convenience build_libtool_libs=no ;; *) oldobjs="$old_deplibs $non_pic_objects" $preload && test -f "$symfileobj" \ && func_append oldobjs " $symfileobj" addlibs=$old_convenience ;; esac if test -n "$addlibs"; then gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_extract_archives $gentop $addlibs func_append oldobjs " $func_extract_archives_result" fi # Do each command in the archive commands. if test -n "$old_archive_from_new_cmds" && test yes = "$build_libtool_libs"; then cmds=$old_archive_from_new_cmds else # Add any objects from preloaded convenience libraries if test -n "$dlprefiles"; then gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_extract_archives $gentop $dlprefiles func_append oldobjs " $func_extract_archives_result" fi # POSIX demands no paths to be encoded in archives. We have # to avoid creating archives with duplicate basenames if we # might have to extract them afterwards, e.g., when creating a # static archive out of a convenience library, or when linking # the entirety of a libtool archive into another (currently # not supported by libtool). if (for obj in $oldobjs do func_basename "$obj" $ECHO "$func_basename_result" done | sort | sort -uc >/dev/null 2>&1); then : else echo "copying selected object files to avoid basename conflicts..." gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_mkdir_p "$gentop" save_oldobjs=$oldobjs oldobjs= counter=1 for obj in $save_oldobjs do func_basename "$obj" objbase=$func_basename_result case " $oldobjs " in " ") oldobjs=$obj ;; *[\ /]"$objbase "*) while :; do # Make sure we don't pick an alternate name that also # overlaps. newobj=lt$counter-$objbase func_arith $counter + 1 counter=$func_arith_result case " $oldobjs " in *[\ /]"$newobj "*) ;; *) if test ! -f "$gentop/$newobj"; then break; fi ;; esac done func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" func_append oldobjs " $gentop/$newobj" ;; *) func_append oldobjs " $obj" ;; esac done fi func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 tool_oldlib=$func_to_tool_file_result eval cmds=\"$old_archive_cmds\" func_len " $cmds" len=$func_len_result if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then cmds=$old_archive_cmds elif test -n "$archiver_list_spec"; then func_verbose "using command file archive linking..." for obj in $oldobjs do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" done > $output_objdir/$libname.libcmd func_to_tool_file "$output_objdir/$libname.libcmd" oldobjs=" $archiver_list_spec$func_to_tool_file_result" cmds=$old_archive_cmds else # the command line is too long to link in one step, link in parts func_verbose "using piecewise archive linking..." save_RANLIB=$RANLIB RANLIB=: objlist= concat_cmds= save_oldobjs=$oldobjs oldobjs= # Is there a better way of finding the last object in the list? for obj in $save_oldobjs do last_oldobj=$obj done eval test_cmds=\"$old_archive_cmds\" func_len " $test_cmds" len0=$func_len_result len=$len0 for obj in $save_oldobjs do func_len " $obj" func_arith $len + $func_len_result len=$func_arith_result func_append objlist " $obj" if test "$len" -lt "$max_cmd_len"; then : else # the above command should be used before it gets too long oldobjs=$objlist if test "$obj" = "$last_oldobj"; then RANLIB=$save_RANLIB fi test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\$concat_cmds$old_archive_cmds\" objlist= len=$len0 fi done RANLIB=$save_RANLIB oldobjs=$objlist if test -z "$oldobjs"; then eval cmds=\"\$concat_cmds\" else eval cmds=\"\$concat_cmds~\$old_archive_cmds\" fi fi fi func_execute_cmds "$cmds" 'exit $?' done test -n "$generated" && \ func_show_eval "${RM}r$generated" # Now create the libtool archive. case $output in *.la) old_library= test yes = "$build_old_libs" && old_library=$libname.$libext func_verbose "creating $output" # Preserve any variables that may affect compiler behavior for var in $variables_saved_for_relink; do if eval test -z \"\${$var+set}\"; then relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else func_quote_arg pretty,unquoted "$var_value" relink_command="$var=$func_quote_arg_unquoted_result; export $var; $relink_command" fi done # Quote the link command for shipping. func_quote eval cd "`pwd`" relink_command="($func_quote_result; $SHELL \"$progpath\" $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" func_quote_arg pretty,unquoted "$relink_command" relink_command=$func_quote_arg_unquoted_result if test yes = "$hardcode_automatic"; then relink_command= fi # Only create the output if not a dry run. $opt_dry_run || { for installed in no yes; do if test yes = "$installed"; then if test -z "$install_libdir"; then break fi output=$output_objdir/${outputname}i # Replace all uninstalled libtool libraries with the installed ones newdependency_libs= for deplib in $dependency_libs; do case $deplib in *.la) func_basename "$deplib" name=$func_basename_result func_resolve_sysroot "$deplib" eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result` test -z "$libdir" && \ func_fatal_error "'$deplib' is not a valid libtool archive" func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name" ;; -L*) func_stripname -L '' "$deplib" func_replace_sysroot "$func_stripname_result" func_append newdependency_libs " -L$func_replace_sysroot_result" ;; -R*) func_stripname -R '' "$deplib" func_replace_sysroot "$func_stripname_result" func_append newdependency_libs " -R$func_replace_sysroot_result" ;; *) func_append newdependency_libs " $deplib" ;; esac done dependency_libs=$newdependency_libs newdlfiles= for lib in $dlfiles; do case $lib in *.la) func_basename "$lib" name=$func_basename_result eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib` test -z "$libdir" && \ func_fatal_error "'$lib' is not a valid libtool archive" func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name" ;; *) func_append newdlfiles " $lib" ;; esac done dlfiles=$newdlfiles newdlprefiles= for lib in $dlprefiles; do case $lib in *.la) # Only pass preopened files to the pseudo-archive (for # eventual linking with the app. that links it) if we # didn't already link the preopened objects directly into # the library: func_basename "$lib" name=$func_basename_result eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib` test -z "$libdir" && \ func_fatal_error "'$lib' is not a valid libtool archive" func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name" ;; esac done dlprefiles=$newdlprefiles else newdlfiles= for lib in $dlfiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;; *) abs=`pwd`"/$lib" ;; esac func_append newdlfiles " $abs" done dlfiles=$newdlfiles newdlprefiles= for lib in $dlprefiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;; *) abs=`pwd`"/$lib" ;; esac func_append newdlprefiles " $abs" done dlprefiles=$newdlprefiles fi $RM $output # place dlname in correct position for cygwin # In fact, it would be nice if we could use this code for all target # systems that can't hard-code library paths into their executables # and that have no shared library path variable independent of PATH, # but it turns out we can't easily determine that from inspecting # libtool variables, so we have to hard-code the OSs to which it # applies here; at the moment, that means platforms that use the PE # object format with DLL files. See the long comment at the top of # tests/bindir.at for full details. tdlname=$dlname case $host,$output,$installed,$module,$dlname in *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) # If a -bindir argument was supplied, place the dll there. if test -n "$bindir"; then func_relative_path "$install_libdir" "$bindir" tdlname=$func_relative_path_result/$dlname else # Otherwise fall back on heuristic. tdlname=../bin/$dlname fi ;; esac $ECHO > $output "\ # $outputname - a libtool library file # Generated by $PROGRAM (GNU $PACKAGE) $VERSION # # Please DO NOT delete this file! # It is necessary for linking the library. # The name that we can dlopen(3). dlname='$tdlname' # Names of this library. library_names='$library_names' # The name of the static archive. old_library='$old_library' # Linker flags that cannot go in dependency_libs. inherited_linker_flags='$new_inherited_linker_flags' # Libraries that this one depends upon. dependency_libs='$dependency_libs' # Names of additional weak libraries provided by this library weak_library_names='$weak_libs' # Version information for $libname. current=$current age=$age revision=$revision # Is this an already installed library? installed=$installed # Should we warn about portability when linking against -modules? shouldnotlink=$module # Files to dlopen/dlpreopen dlopen='$dlfiles' dlpreopen='$dlprefiles' # Directory that this library needs to be installed in: libdir='$install_libdir'" if test no,yes = "$installed,$need_relink"; then $ECHO >> $output "\ relink_command=\"$relink_command\"" fi done } # Do a symbolic link so that the libtool archive can be found in # LD_LIBRARY_PATH before the program is installed. func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?' ;; esac exit $EXIT_SUCCESS } if test link = "$opt_mode" || test relink = "$opt_mode"; then func_mode_link ${1+"$@"} fi # func_mode_uninstall arg... func_mode_uninstall () { $debug_cmd RM=$nonopt files= rmforce=false exit_status=0 # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic=$magic for arg do case $arg in -f) func_append RM " $arg"; rmforce=: ;; -*) func_append RM " $arg" ;; *) func_append files " $arg" ;; esac done test -z "$RM" && \ func_fatal_help "you must specify an RM program" rmdirs= for file in $files; do func_dirname "$file" "" "." dir=$func_dirname_result if test . = "$dir"; then odir=$objdir else odir=$dir/$objdir fi func_basename "$file" name=$func_basename_result test uninstall = "$opt_mode" && odir=$dir # Remember odir for removal later, being careful to avoid duplicates if test clean = "$opt_mode"; then case " $rmdirs " in *" $odir "*) ;; *) func_append rmdirs " $odir" ;; esac fi # Don't error if the file doesn't exist and rm -f was used. if { test -L "$file"; } >/dev/null 2>&1 || { test -h "$file"; } >/dev/null 2>&1 || test -f "$file"; then : elif test -d "$file"; then exit_status=1 continue elif $rmforce; then continue fi rmfiles=$file case $name in *.la) # Possibly a libtool archive, so verify it. if func_lalib_p "$file"; then func_source $dir/$name # Delete the libtool libraries and symlinks. for n in $library_names; do func_append rmfiles " $odir/$n" done test -n "$old_library" && func_append rmfiles " $odir/$old_library" case $opt_mode in clean) case " $library_names " in *" $dlname "*) ;; *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;; esac test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i" ;; uninstall) if test -n "$library_names"; then # Do each command in the postuninstall commands. func_execute_cmds "$postuninstall_cmds" '$rmforce || exit_status=1' fi if test -n "$old_library"; then # Do each command in the old_postuninstall commands. func_execute_cmds "$old_postuninstall_cmds" '$rmforce || exit_status=1' fi # FIXME: should reinstall the best remaining shared library. ;; esac fi ;; *.lo) # Possibly a libtool object, so verify it. if func_lalib_p "$file"; then # Read the .lo file func_source $dir/$name # Add PIC object to the list of files to remove. if test -n "$pic_object" && test none != "$pic_object"; then func_append rmfiles " $dir/$pic_object" fi # Add non-PIC object to the list of files to remove. if test -n "$non_pic_object" && test none != "$non_pic_object"; then func_append rmfiles " $dir/$non_pic_object" fi fi ;; *) if test clean = "$opt_mode"; then noexename=$name case $file in *.exe) func_stripname '' '.exe' "$file" file=$func_stripname_result func_stripname '' '.exe' "$name" noexename=$func_stripname_result # $file with .exe has already been added to rmfiles, # add $file without .exe func_append rmfiles " $file" ;; esac # Do a test to see if this is a libtool program. if func_ltwrapper_p "$file"; then if func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" relink_command= func_source $func_ltwrapper_scriptname_result func_append rmfiles " $func_ltwrapper_scriptname_result" else relink_command= func_source $dir/$noexename fi # note $name still contains .exe if it was in $file originally # as does the version of $file that was added into $rmfiles func_append rmfiles " $odir/$name $odir/${name}S.$objext" if test yes = "$fast_install" && test -n "$relink_command"; then func_append rmfiles " $odir/lt-$name" fi if test "X$noexename" != "X$name"; then func_append rmfiles " $odir/lt-$noexename.c" fi fi fi ;; esac func_show_eval "$RM $rmfiles" 'exit_status=1' done # Try to remove the $objdir's in the directories where we deleted files for dir in $rmdirs; do if test -d "$dir"; then func_show_eval "rmdir $dir >/dev/null 2>&1" fi done exit $exit_status } if test uninstall = "$opt_mode" || test clean = "$opt_mode"; then func_mode_uninstall ${1+"$@"} fi test -z "$opt_mode" && { help=$generic_help func_fatal_help "you must specify a MODE" } test -z "$exec_cmd" && \ func_fatal_help "invalid operation mode '$opt_mode'" if test -n "$exec_cmd"; then eval exec "$exec_cmd" exit $EXIT_FAILURE fi exit $exit_status # The TAGs below are defined such that we never get into a situation # where we disable both kinds of libraries. Given conflicting # choices, we go for a static library, that is the most portable, # since we can't tell whether shared libraries were disabled because # the user asked for that or because the platform doesn't support # them. This is particularly important on AIX, because we don't # support having both static and shared libraries enabled at the same # time on that platform, so we default to a shared-only configuration. # If a disable-shared tag is given, we'll fallback to a static-only # configuration. But we'll never go from static-only to shared-only. # ### BEGIN LIBTOOL TAG CONFIG: disable-shared build_libtool_libs=no build_old_libs=yes # ### END LIBTOOL TAG CONFIG: disable-shared # ### BEGIN LIBTOOL TAG CONFIG: disable-static build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` # ### END LIBTOOL TAG CONFIG: disable-static # Local Variables: # mode:shell-script # sh-indentation:2 # End: geany-2.0/ctags/0000755000175000017500000000000014514253232010561 500000000000000geany-2.0/ctags/Makefile.am0000644000175000017500000001311514514252267012545 00000000000000AM_CPPFLAGS = \ -I$(srcdir)/main \ -I$(srcdir)/parsers \ -I$(srcdir)/dsl \ -DEXTERNAL_PARSER_LIST_FILE=\"$(top_srcdir)/src/tagmanager/tm_parsers.h\" \ -DG_LOG_DOMAIN=\"CTags\" AM_CFLAGS = \ $(GTK_CFLAGS) \ @LIBGEANY_CFLAGS@ noinst_LTLIBRARIES = libctags.la parsers = \ parsers/cxx/cxx.c \ parsers/cxx/cxx_debug.c \ parsers/cxx/cxx_debug.h \ parsers/cxx/cxx_debug_type.c \ parsers/cxx/cxx_keyword.c \ parsers/cxx/cxx_keyword.h \ parsers/cxx/cxx_parser_block.c \ parsers/cxx/cxx_parser.c \ parsers/cxx/cxx_parser_function.c \ parsers/cxx/cxx_parser.h \ parsers/cxx/cxx_parser_internal.h \ parsers/cxx/cxx_parser_lambda.c \ parsers/cxx/cxx_parser_namespace.c \ parsers/cxx/cxx_parser_template.c \ parsers/cxx/cxx_parser_tokenizer.c \ parsers/cxx/cxx_parser_typedef.c \ parsers/cxx/cxx_parser_using.c \ parsers/cxx/cxx_parser_variable.c \ parsers/cxx/cxx_qtmoc.c \ parsers/cxx/cxx_scope.c \ parsers/cxx/cxx_scope.h \ parsers/cxx/cxx_subparser.c \ parsers/cxx/cxx_subparser.h \ parsers/cxx/cxx_subparser_internal.h \ parsers/cxx/cxx_tag.c \ parsers/cxx/cxx_tag.h \ parsers/cxx/cxx_token.c \ parsers/cxx/cxx_token_chain.c \ parsers/cxx/cxx_token_chain.h \ parsers/cxx/cxx_token.h \ parsers/cpreprocessor.c \ parsers/cpreprocessor.h \ parsers/abaqus.c \ parsers/abc.c \ parsers/ada.c \ parsers/asciidoc.c \ parsers/asm.c \ parsers/autoit.c \ parsers/basic.c \ parsers/bibtex.c \ parsers/geany_c.c \ parsers/clojure.c \ parsers/cobol.c \ parsers/iniconf.c \ parsers/iniconf.h \ parsers/css.c \ parsers/diff.c \ parsers/geany_docbook.c \ parsers/dosbatch.c \ parsers/erlang.c \ parsers/flex.c \ parsers/fortran.c \ parsers/gdscript.c \ parsers/go.c \ parsers/haskell.c \ parsers/haxe.c \ parsers/html.c \ parsers/jscript.c \ parsers/json.c \ parsers/julia.c \ parsers/geany_lcpp.c \ parsers/geany_lcpp.h \ parsers/lisp.c \ parsers/lua.c \ parsers/make.c \ parsers/make.h \ parsers/markdown.c \ parsers/markdown.h \ parsers/geany_matlab.c \ parsers/nsis.c \ parsers/objc.c \ parsers/pascal.c \ parsers/perl.c \ parsers/perl.h \ parsers/php.c \ parsers/powershell.c \ parsers/python.c \ parsers/r.c \ parsers/r.h \ parsers/rst.c \ parsers/ruby.c \ parsers/rust.c \ parsers/sh.c \ parsers/sql.c \ parsers/tcl.c \ parsers/tcl.h \ parsers/tcloo.c \ parsers/tex.c \ parsers/tex.h \ parsers/txt2tags.c \ parsers/typescript.c \ parsers/verilog.c \ parsers/vhdl.c # skip cmd.c and mini-geany.c which define main() # also skip lregex-pcre2.c which we don't use libctags_la_SOURCES = \ dsl/optscript.c \ dsl/optscript.h \ dsl/es.c \ dsl/es.h \ libreadtags/readtags.c \ libreadtags/readtags.h \ main/args.c \ main/args_p.h \ main/colprint.c \ main/colprint_p.h \ main/CommonPrelude.c \ main/ctags.h \ main/debug.c \ main/debug.h \ main/dependency.c \ main/dependency.h \ main/dependency_p.h \ main/e_msoft.h \ main/entry.c \ main/entry.h \ main/entry_p.h \ main/entry_private.c \ main/error.c \ main/error_p.h \ main/field.c \ main/field.h \ main/field_p.h \ main/flags.c \ main/flags_p.h \ main/fmt.c \ main/fmt_p.h \ main/gcc-attr.h \ main/general.h \ main/gvars.h \ main/htable.c \ main/htable.h \ main/inline.h \ main/interactive_p.h \ main/keyword.c \ main/keyword.h \ main/keyword_p.h \ main/kind.c \ main/kind.h \ main/kind_p.h \ main/lregex.c \ main/lregex.h \ main/lregex_p.h \ main/lregex-default.c \ main/lxpath.c \ main/lxpath.h \ main/lxpath_p.h \ main/main.c \ main/main_p.h \ main/mbcs.c \ main/mbcs.h \ main/mbcs_p.h \ main/mio.c \ main/mio.h \ main/nestlevel.c \ main/nestlevel.h \ main/numarray.c \ main/numarray.h \ main/objpool.c \ main/objpool.h \ main/options.c \ main/options.h \ main/options_p.h \ main/param.c \ main/param.h \ main/param_p.h \ main/parse.c \ main/parse.h \ main/parse_p.h \ main/parsers_p.h \ main/portable-dirent_p.h \ main/portable-scandir.c \ main/promise.c \ main/promise.h \ main/promise_p.h \ main/ptag.c \ main/ptag_p.h \ main/ptrarray.c \ main/ptrarray.h \ main/rbtree.c \ main/rbtree.h \ main/read.c \ main/read.h \ main/read_p.h \ main/repoinfo.c \ main/repoinfo.h \ main/routines.c \ main/routines.h \ main/routines_p.h \ main/script.c \ main/script_p.h \ main/seccomp.c \ main/selectors.c \ main/selectors.h \ main/sort.c \ main/sort_p.h \ main/stats.c \ main/stats_p.h \ main/strlist.c \ main/strlist.h \ main/subparser.h \ main/subparser_p.h \ main/tokeninfo.c \ main/tokeninfo.h \ main/trace.c \ main/trace.h \ main/trashbox.c \ main/trashbox.h \ main/trashbox_p.h \ main/types.h \ main/unwindi.c \ main/unwindi.h \ main/vstring.c \ main/vstring.h \ main/writer-ctags.c \ main/writer-etags.c \ main/writer-json.c \ main/writer-xref.c \ main/writer.c \ main/writer_p.h \ main/xtag.c \ main/xtag.h \ main/xtag_p.h \ $(parsers) libctags_la_LIBADD = # build bundled GNU regex if needed if USE_BUNDLED_REGEX noinst_LTLIBRARIES += libgnu_regex.la libgnu_regex_la_SOURCES = \ gnu_regex/regex.c \ gnu_regex/regex.h # regex.c includes other sources we have to distribute EXTRA_libgnu_regex_la_SOURCES = \ gnu_regex/regcomp.c \ gnu_regex/regex.c \ gnu_regex/regex.h \ gnu_regex/regex_internal.c \ gnu_regex/regex_internal.h \ gnu_regex/regexec.c libgnu_regex_la_CPPFLAGS = -D__USE_GNU EXTRA_DIST = \ gnu_regex/README.txt libctags_la_LIBADD += libgnu_regex.la AM_CPPFLAGS += -I$(srcdir)/gnu_regex endif # build bundled fnmatch if needed if USE_BUNDLED_FNMATCH noinst_LTLIBRARIES += libfnmatch.la libfnmatch_la_SOURCES = \ fnmatch/fnmatch.c \ fnmatch/fnmatch.h libctags_la_LIBADD += libfnmatch.la AM_CPPFLAGS += -I$(srcdir)/fnmatch endif geany-2.0/ctags/parsers/0000755000175000017500000000000014514253232012240 500000000000000geany-2.0/ctags/parsers/verilog.c0000644000175000017500000016030114514252267014003 00000000000000/* * Copyright (c) 2003, Darren Hiebert * Copyright (c) 2017, Vitor Antunes * Copyright (c) 2020, Hiroo Hayashi * * This source code is released for free distribution under the terms of the * GNU General Public License version 2 or (at your option) any later version. * * This module contains functions for generating tags for the Verilog or * SystemVerilog HDL (Hardware Description Language). * * References: * IEEE Std 1800-2017, SystemVerilog Language Reference Manual * https://ieeexplore.ieee.org/document/8299595 * SystemVerilog IEEE Std 1800-2012 Grammer * https://insights.sigasi.com/tech/systemverilog.ebnf/ * Verilog Formal Syntax Specification * http://www.verilog.com/VerilogBNF.html */ /* * INCLUDE FILES */ #include "general.h" /* must always come first */ #include #include "debug.h" #include "entry.h" #include "keyword.h" #include "options.h" #include "parse.h" #include "read.h" #include "routines.h" #include "xtag.h" #include "ptrarray.h" /* * MACROS */ #define NUMBER_LANGUAGES 2 /* Indicates number of defined indexes */ #define IDX_SYSTEMVERILOG 0 #define IDX_VERILOG 1 /* * DATA DECLARATIONS */ /* A callback function searching a symbol from the cork symbol table assumes * this kind definitions are shared in Verilog and SystemVerilog parsers. * If you will separate the definitions for the parsers, you must revise the * code related to the symbol table. */ typedef enum { /* parser private items */ K_IGNORE = -16, /* Verilog/SystemVerilog keywords to be ignored */ K_DEFINE, K_DIRECTIVE, K_END, K_END_DE, /* End of Design Elements */ K_IDENTIFIER, K_LOCALPARAM, K_PARAMETER, K_IMPORT, K_WITH, K_UNDEFINED = KEYWORD_NONE, /* the followings items are also used as indices for VerilogKinds[] and SystemVerilogKinds[] */ K_CONSTANT= 0, K_EVENT, K_FUNCTION, K_MODULE, K_NET, K_PORT, K_REGISTER, K_TASK, K_BLOCK, K_INSTANCE, K_ASSERTION, K_CLASS, K_COVERGROUP, K_ENUM, K_INTERFACE, K_MODPORT, K_PACKAGE, K_PROGRAM, K_PROTOTYPE, K_PROPERTY, K_STRUCT, K_TYPEDEF, K_CHECKER, K_CLOCKING, K_SEQUENCE, K_MEMBER, K_IFCLASS, /* interface class */ K_CONSTRAINT, K_NETTYPE, } verilogKind; typedef struct { const char *keyword; verilogKind kind; short isValid [NUMBER_LANGUAGES]; } keywordAssoc; typedef struct sTokenInfo { verilogKind kind; vString* name; /* the name of the token */ unsigned long lineNumber; /* line number where token was found */ MIOPos filePosition; /* file position where token was found */ struct sTokenInfo* scope; /* context of keyword */ int nestLevel; /* Current nest level */ verilogKind lastKind; /* Kind of last found tag */ vString* blockName; /* Current block name */ vString* inheritance; /* Class inheritance */ bool prototype; /* Is only a prototype */ bool classScope; /* Context is local to the current sub-context */ bool parameter; /* parameter which can be overridden */ bool hasParamList; /* module definition has a parameter port list */ } tokenInfo; typedef enum { F_PARAMETER, } verilogField; /* * DATA DEFINITIONS */ static int Ungetc; static int Lang_verilog; static int Lang_systemverilog; static kindDefinition VerilogKinds [] = { { true, 'c', "constant", "constants (define, parameter, specparam)" }, { true, 'e', "event", "events" }, { true, 'f', "function", "functions" }, { true, 'm', "module", "modules" }, { true, 'n', "net", "net data types" }, { true, 'p', "port", "ports" }, { true, 'r', "register", "variable data types" }, { true, 't', "task", "tasks" }, { true, 'b', "block", "blocks (begin, fork)" }, { true, 'i', "instance", "instances of module" }, }; static kindDefinition SystemVerilogKinds [] = { { true, 'c', "constant", "constants (define, parameter, specparam, enum values)" }, { true, 'e', "event", "events" }, { true, 'f', "function", "functions" }, { true, 'm', "module", "modules" }, { true, 'n', "net", "net data types" }, { true, 'p', "port", "ports" }, { true, 'r', "register", "variable data types" }, { true, 't', "task", "tasks" }, { true, 'b', "block", "blocks (begin, fork)" }, { true, 'i', "instance", "instances of module or interface" }, { true, 'A', "assert", "assertions (assert, assume, cover, restrict)" }, { true, 'C', "class", "classes" }, { true, 'V', "covergroup","covergroups" }, { true, 'E', "enum", "enumerators" }, { true, 'I', "interface", "interfaces" }, { true, 'M', "modport", "modports" }, { true, 'K', "package", "packages" }, { true, 'P', "program", "programs" }, { false,'Q', "prototype", "prototypes (extern, pure)" }, { true, 'R', "property", "properties" }, { true, 'S', "struct", "structs and unions" }, { true, 'T', "typedef", "type declarations" }, { true, 'H', "checker", "checkers" }, { true, 'L', "clocking", "clocking" }, { true, 'q', "sequence", "sequences" }, { true, 'w', "member", "struct and union members" }, { true, 'l', "ifclass", "interface class" }, { true, 'O', "constraint","constraints" }, { true, 'N', "nettype", "nettype declarations" }, }; static const keywordAssoc KeywordTable [] = { /* SystemVerilog */ /* | Verilog */ /* keyword keyword ID | | */ { "`define", K_DEFINE, { 1, 1 } }, { "begin", K_BLOCK, { 1, 1 } }, { "end", K_END, { 1, 1 } }, { "endfunction", K_END_DE, { 1, 1 } }, { "endmodule", K_END_DE, { 1, 1 } }, { "endtask", K_END_DE, { 1, 1 } }, { "event", K_EVENT, { 1, 1 } }, { "fork", K_BLOCK, { 1, 1 } }, { "function", K_FUNCTION, { 1, 1 } }, { "genvar", K_REGISTER, { 1, 1 } }, { "inout", K_PORT, { 1, 1 } }, { "input", K_PORT, { 1, 1 } }, { "integer", K_REGISTER, { 1, 1 } }, { "join", K_END, { 1, 1 } }, { "localparam", K_LOCALPARAM, { 1, 1 } }, { "module", K_MODULE, { 1, 1 } }, { "output", K_PORT, { 1, 1 } }, { "parameter", K_PARAMETER, { 1, 1 } }, { "real", K_REGISTER, { 1, 1 } }, { "realtime", K_REGISTER, { 1, 1 } }, { "reg", K_REGISTER, { 1, 1 } }, { "signed", K_IGNORE, { 1, 1 } }, { "specparam", K_CONSTANT, { 1, 1 } }, { "supply0", K_NET, { 1, 1 } }, { "supply1", K_NET, { 1, 1 } }, { "task", K_TASK, { 1, 1 } }, { "time", K_REGISTER, { 1, 1 } }, { "tri", K_NET, { 1, 1 } }, { "triand", K_NET, { 1, 1 } }, { "trior", K_NET, { 1, 1 } }, { "trireg", K_NET, { 1, 1 } }, { "tri0", K_NET, { 1, 1 } }, { "tri1", K_NET, { 1, 1 } }, { "uwire", K_NET, { 1, 1 } }, { "wand", K_NET, { 1, 1 } }, { "wire", K_NET, { 1, 1 } }, { "wor", K_NET, { 1, 1 } }, { "assert", K_ASSERTION, { 1, 0 } }, { "assume", K_ASSERTION, { 1, 0 } }, { "bit", K_REGISTER, { 1, 0 } }, { "byte", K_REGISTER, { 1, 0 } }, { "chandle", K_REGISTER, { 1, 0 } }, { "checker", K_CHECKER, { 1, 0 } }, { "class", K_CLASS, { 1, 0 } }, { "constraint", K_CONSTRAINT, { 1, 0 } }, { "cover", K_ASSERTION, { 1, 0 } }, { "clocking", K_CLOCKING, { 1, 0 } }, { "covergroup", K_COVERGROUP, { 1, 0 } }, { "endchecker", K_END_DE, { 1, 0 } }, { "endclass", K_END_DE, { 1, 0 } }, { "endclocking", K_END_DE, { 1, 0 } }, { "endgroup", K_END_DE, { 1, 0 } }, { "endinterface", K_END_DE, { 1, 0 } }, { "endpackage", K_END_DE, { 1, 0 } }, { "endprogram", K_END_DE, { 1, 0 } }, { "endproperty", K_END_DE, { 1, 0 } }, { "endsequence", K_END_DE, { 1, 0 } }, { "enum", K_ENUM, { 1, 0 } }, { "extern", K_PROTOTYPE, { 1, 0 } }, { "import", K_IMPORT, { 1, 0 } }, { "int", K_REGISTER, { 1, 0 } }, { "interconnect", K_NET, { 1, 0 } }, { "interface", K_INTERFACE, { 1, 0 } }, { "join_any", K_END, { 1, 0 } }, { "join_none", K_END, { 1, 0 } }, { "logic", K_REGISTER, { 1, 0 } }, { "longint", K_REGISTER, { 1, 0 } }, { "modport", K_MODPORT, { 1, 0 } }, { "package", K_PACKAGE, { 1, 0 } }, { "program", K_PROGRAM, { 1, 0 } }, { "property", K_PROPERTY, { 1, 0 } }, { "pure", K_PROTOTYPE, { 1, 0 } }, { "ref", K_PORT, { 1, 0 } }, { "restrict", K_ASSERTION, { 1, 0 } }, { "sequence", K_SEQUENCE, { 1, 0 } }, { "shortint", K_REGISTER, { 1, 0 } }, { "shortreal", K_REGISTER, { 1, 0 } }, { "string", K_REGISTER, { 1, 0 } }, { "struct", K_STRUCT, { 1, 0 } }, { "type", K_REGISTER, { 1, 0 } }, { "typedef", K_TYPEDEF, { 1, 0 } }, { "union", K_STRUCT, { 1, 0 } }, { "var", K_REGISTER, { 1, 0 } }, { "void", K_REGISTER, { 1, 0 } }, { "with", K_WITH, { 1, 0 } }, { "nettype", K_NETTYPE, { 1, 0 } }, // { "virtual", K_PROTOTYPE, { 1, 0 } }, // do not add for now }; static tokenInfo *currentContext = NULL; static ptrArray *tagContents; static fieldDefinition *fieldTable = NULL; // IEEE Std 1364-2005 LRM, Appendix B "List of Keywords" const static struct keywordGroup verilogKeywords = { .value = K_IGNORE, .addingUnlessExisting = true, .keywords = { "always", "and", "assign", "automatic", "begin", "buf", "bufif0", "bufif1", "case", "casex", "casez", "cell", "cmos", "config", "deassign", "default", "defparam", "design", "disable", "edge", "else", "end", "endcase", "endconfig", "endfunction", "endgenerate", "endmodule", "endprimitive", "endspecify", "endtable", "endtask", "event", "for", "force", "forever", "fork", "function", "generate", "genvar", "highz0", "highz1", "if", "ifnone", "incdir", "include", "initial", "inout", "input", "instance", "integer", "join", "large", "liblist", "library", "localparam", "macromodule", "medium", "module", "nand", "negedge", "nmos", "nor", "noshowcancelled", "not", "notif0", "notif1", "or", "output", "parameter", "pmos", "posedge", "primitive", "pull0", "pull1", "pulldown", "pullup", "pulsestyle_onevent", "pulsestyle_ondetect", "rcmos", "real", "realtime", "reg", "release", "repeat", "rnmos", "rpmos", "rtran", "rtranif0", "rtranif1", "scalared", "showcancelled", "signed", "small", "specify", "specparam", "strong0", "strong1", "supply0", "supply1", "table", "task", "time", "tran", "tranif0", "tranif1", "tri", "tri0", "tri1", "triand", "trior", "trireg", "unsigned1", "use", "uwire", "vectored", "wait", "wand", "weak0", "weak1", "while", "wire", "wor", "xnor", "xor", NULL }, }; // IEEE Std 1800-2017 LRM, Annex B "Keywords" const static struct keywordGroup systemVerilogKeywords = { .value = K_IGNORE, .addingUnlessExisting = true, .keywords = { "accept_on", "alias", "always", "always_comb", "always_ff", "always_latch", "and", "assert", "assign", "assume", "automatic", "before", "begin", "bind", "bins", "binsof", "bit", "break", "buf", "bufif0", "bufif1", "byte", "case", "casex", "casez", "cell", "chandle", "checker", "class", "clocking", "cmos", "config", "const", "constraint", "context", "continue", "cover", "covergroup", "coverpoint", "cross", "deassign", "default", "defparam", "design", "disable", "dist", "do", "edge", "else", "end", "endcase", "endchecker", "endclass", "endclocking", "endconfig", "endfunction", "endgenerate", "endgroup", "endinterface", "endmodule", "endpackage", "endprimitive", "endprogram", "endproperty", "endspecify", "endsequence", "endtable", "endtask", "enum", "event", "eventually", "expect", "export", "extends", "extern", "final", "first_match", "for", "force", "foreach", "forever", "fork", "forkjoin", "function", "generate", "genvar", "global", "highz0", "highz1", "if", "iff", "ifnone", "ignore_bins", "illegal_bins", "implements", "implies", "import", "incdir", "include", "initial", "inout", "input", "inside", "instance", "int", "integer", "interconnect", "interface", "intersect", "join", "join_any", "join_none", "large", "let", "liblist", "library", "local", "localparam", "logic", "longint", "macromodule", "matches", "medium", "modport", "module", "nand", "negedge", "nettype", "new", "nexttime", "nmos", "nor", "noshowcancelled", "not", "notif0", "notif1", "null", "or", "output", "package", "packed", "parameter", "pmos", "posedge", "primitive", "priority", "program", "property", "protected", "pull0", "pull1", "pulldown", "pullup", "pulsestyle_ondetect", "pulsestyle_onevent", "pure", "rand", "randc", "randcase", "randsequence", "rcmos", "real", "realtime", "ref", "reg", "reject_on", "release", "repeat", "restrict", "return", "rnmos", "rpmos", "rtran", "rtranif0", "rtranif1", "s_always", "s_eventually", "s_nexttime", "s_until", "s_until_with", "scalared", "sequence", "shortint", "shortreal", "showcancelled", "signed", "small", "soft", "solve", "specify", "specparam", "static", "string", "strong", "strong0", "strong1", "struct", "super", "supply0", "supply1", "sync_accept_on", "sync_reject_on", "table", "tagged", "task", "this", "throughout", "time", "timeprecision", "timeunit", "tran", "tranif0", "tranif1", "tri", "tri0", "tri1", "triand", "trior", "trireg", "type", "typedef", "union", "unique", "unique0", "unsigned", "until", "until_with", "untyped", "use", "uwire", "var", "vectored", "virtual", "void", "wait", "wait_order", "wand", "weak", "weak0", "weak1", "while", "wildcard", "wire", "with", "within", "wor", "xnor", "xor", NULL }, }; // IEEE Std 1364-2005 LRM, "19. Compiler directives" const static struct keywordGroup verilogDirectives = { .value = K_DIRECTIVE, .addingUnlessExisting = true, .keywords = { "`begin_keywords", "`celldefine", "`default_nettype", "`define", "`else", "`elsif", "`end_keywords", "`endcelldefine", "`endif", "`ifdef", "`ifndef", "`include", "`line", "`nounconnected_drive", "`pragma", "`resetall", "`timescale", "`unconnected_drive", "`undef", NULL }, }; // IEEE Std 1800-2017 LRM, "22. Compiler directives" const static struct keywordGroup systemVerilogDirectives = { .value = K_DIRECTIVE, .addingUnlessExisting = true, .keywords = { "`__LINE__", "`begin_keywords", "`celldefine", "`default_nettype", "`define", "`else", "`elsif", "`end_keywords", "`endcelldefine", "`endif", "`ifdef", "`ifndef", "`include", "`line", "`nounconnected_drive", "`pragma", "`resetall", "`timescale", "`unconnected_drive", "`undef", "`undefineall", NULL }, }; // .enabled field cannot be shared by two languages static fieldDefinition VerilogFields[] = { { .name = "parameter", .description = "parameter whose value can be overridden.", .enabled = false, .dataType = FIELDTYPE_BOOL }, }; static fieldDefinition SystemVerilogFields[] = { { .name = "parameter", .description = "parameter whose value can be overridden.", .enabled = false, .dataType = FIELDTYPE_BOOL }, }; /* * PROTOTYPE DEFINITIONS */ static bool isIdentifier (tokenInfo* token); static int processDefine (tokenInfo *const token, int c); static int processType (tokenInfo* token, int c, verilogKind* kind, bool* with); static int pushEnumNames (tokenInfo* token, int c); static int pushMembers (tokenInfo* token, int c); static int readWordToken (tokenInfo *const token, int c); static int readWordTokenNoSkip (tokenInfo *const token, int c); static int skipBlockName (tokenInfo *const token, int c); static int skipClockEvent (tokenInfo* token, int c); static int skipDelay (tokenInfo* token, int c); static int tagIdentifierList (tokenInfo *const token, int c, verilogKind kind, bool mayPortDecl); static int tagNameList (tokenInfo* token, int c, verilogKind kind); /* * FUNCTION DEFINITIONS */ static short isContainer (verilogKind kind) { switch (kind) { case K_MODULE: case K_TASK: case K_FUNCTION: case K_BLOCK: case K_CHECKER: case K_CLASS: case K_CLOCKING: case K_COVERGROUP: case K_IFCLASS: case K_INTERFACE: case K_PACKAGE: case K_PROGRAM: case K_PROPERTY: case K_SEQUENCE: case K_TYPEDEF: case K_NETTYPE: case K_ENUM: case K_STRUCT: return true; default: return false; } } static short isTempContext (tokenInfo const* token) { switch (token->kind) { case K_TYPEDEF: case K_NETTYPE: case K_ENUM: case K_STRUCT: return true; default: return false; } } static void clearToken (tokenInfo *token) { token->kind = K_UNDEFINED; // to be set by updateKind() vStringClear (token->name); token->lineNumber = getInputLineNumber (); token->filePosition = getInputFilePosition (); token->scope = NULL; token->nestLevel = 0; token->lastKind = K_UNDEFINED; vStringClear (token->blockName); vStringClear (token->inheritance); token->prototype = false; token->classScope = false; token->parameter = false; token->hasParamList = false; } static tokenInfo *newToken (void) { tokenInfo *const token = xMalloc (1, tokenInfo); token->name = vStringNew (); token->blockName = vStringNew (); token->inheritance = vStringNew (); clearToken (token); return token; } static tokenInfo *dupToken (tokenInfo *token) { tokenInfo *dup = newToken (); tokenInfo tmp = *dup; // save vStrings, name, blockName, and inheritance *dup = *token; // revert vStrings allocated for dup dup->name = tmp.name; dup->blockName = tmp.blockName; dup->inheritance = tmp.inheritance; // copy contents of vStrings vStringCopy (dup->name, token->name); vStringCopy (dup->blockName, token->blockName); vStringCopy (dup->inheritance, token->inheritance); return dup; } static void deleteToken (tokenInfo * const token) { if (token != NULL) { vStringDelete (token->name); vStringDelete (token->blockName); vStringDelete (token->inheritance); eFree (token); } } static tokenInfo *pushToken (tokenInfo * const token, tokenInfo * const tokenPush) { tokenPush->scope = token; return tokenPush; } static tokenInfo *popToken (tokenInfo * const token) { tokenInfo *localToken; if (token != NULL) { localToken = token->scope; deleteToken (token); return localToken; } return NULL; } static void pruneTokens (tokenInfo * token) { while ((token = popToken (token))) ; } static void swapToken (tokenInfo *t0, tokenInfo *t1) { tokenInfo tmp = *t0; *t0 = *t1; *t1 = tmp; } static const char *getNameForKind (const verilogKind kind) { if (isInputLanguage (Lang_systemverilog)) return (SystemVerilogKinds[kind]).name; else /* isInputLanguage (Lang_verilog) */ return (VerilogKinds[kind]).name; } static char kindEnabled (const verilogKind kind) { if (isInputLanguage (Lang_systemverilog)) return SystemVerilogKinds[kind].enabled; else /* isInputLanguage (Lang_verilog) */ return VerilogKinds[kind].enabled; } static void buildKeywordHash (const langType language, unsigned int idx) { size_t i; const size_t count = ARRAY_SIZE (KeywordTable); for (i = 0 ; i < count ; ++i) { const keywordAssoc *p = &KeywordTable [i]; if (p->isValid [idx]) addKeyword (p->keyword, language, (int) p->kind); } } static void initializeVerilog (const langType language) { Lang_verilog = language; buildKeywordHash (language, IDX_VERILOG); addKeywordGroup (&verilogKeywords, language); addKeywordGroup (&verilogDirectives, language); if (tagContents == NULL) tagContents = ptrArrayNew ((ptrArrayDeleteFunc)deleteToken); } static void initializeSystemVerilog (const langType language) { Lang_systemverilog = language; buildKeywordHash (language, IDX_SYSTEMVERILOG); addKeywordGroup (&systemVerilogKeywords, language); addKeywordGroup (&systemVerilogDirectives, language); if (tagContents == NULL) tagContents = ptrArrayNew ((ptrArrayDeleteFunc)deleteToken); } static void vUngetc (int c) { Assert (Ungetc == '\0'); Ungetc = c; } /* Mostly copied from cppSkipOverCComment() in cpreprocessor.c. * * cppSkipOverCComment() uses the internal ungetc buffer of * CPreProcessor. On the other hand, the Verilog parser uses * getcFromInputFile() directly. getcFromInputFile() uses just * another internal ungetc buffer. Using them mixed way will * cause a trouble. */ static int verilogSkipOverCComment (void) { int c = getcFromInputFile (); while (c != EOF) { if (c != '*') c = getcFromInputFile (); else { const int next = getcFromInputFile (); if (next != '/') c = next; else { c = SPACE; /* replace comment with space */ break; } } } return c; } static int _vGetc (bool inSkipPastMatch) { int c; if (Ungetc == '\0') c = getcFromInputFile (); else { c = Ungetc; Ungetc = '\0'; } if (c == '/') { int c2 = getcFromInputFile (); if (c2 == EOF) return EOF; else if (c2 == '/') /* strip comment until end-of-line */ { do c = getcFromInputFile (); while (c != '\n' && c != EOF); } else if (c2 == '*') /* strip block comment */ c = verilogSkipOverCComment (); else ungetcToInputFile (c2); } // replace a string with "@" only in skipPastMatch() // because the string may contain parens, etc. else if (inSkipPastMatch && c == '"') { int c2; do c2 = getcFromInputFile (); while (c2 != '"' && c2 != EOF); c = '@'; } return c; } static int vGetc (void) { return _vGetc (false); } // Is the first charactor in an identifier? [a-zA-Z_`] static bool isWordToken (const int c) { return (isalpha (c) || c == '_' || c == '`'); } // Is a charactor in an identifier? [a-zA-Z0-9_`$] static bool isIdentifierCharacter (const int c) { return (isalnum (c) || c == '_' || c == '`' || c == '$'); } static int skipWhite (int c) { while (isspace (c)) c = vGetc (); return c; } static int skipPastMatch (const char *const pair) { const int begin = pair [0], end = pair [1]; int matchLevel = 1; int c; do { c = _vGetc (true); if (c == begin) ++matchLevel; else if (c == end) --matchLevel; } while (matchLevel > 0 && c != EOF); return skipWhite (vGetc ()); } static int skipDimension (int c) { while (c == '[' && c != EOF) c = skipPastMatch ("[]"); return c; } static int skipToSemiColon (int c) { while (c != ';' && c != EOF) c = vGetc (); return c; // ';' or EOF } static int skipString (int c) { if (c == '"') { do c = vGetc (); while (c != '"' && c != EOF); } c = skipWhite (vGetc ()); return c; } static int skipExpression (int c) { while (c != ',' && c != ';' && c != ')' && c != '}' && c != ']' && c != EOF) { if (c == '(') c = skipPastMatch ("()"); else if (c == '{') c = skipPastMatch ("{}"); else if (c == '[') c = skipPastMatch ("[]"); else if (c == '"') c = skipString (c); else c = skipWhite (vGetc ()); } return c; } // Skip to newline. The newline preceded by a backslash ( \ ) is ignored. // Should be used after readWordTokenNoSkip() for compiler directives static int skipToNewLine (int c) { bool escape = false; for ( ; (c != '\n' || escape) && c != EOF; c = vGetc ()) escape = (c == '\\'); return c; // '\n' or EOF } static int skipMacro (int c, tokenInfo *token) { tokenInfo *localToken = newToken (); // don't update token outside while (c == '`') // to support back-to-back compiler directives { c = readWordTokenNoSkip (localToken, c); /* Skip compiler directive other than `define */ if (localToken->kind == K_DIRECTIVE) { c = skipToNewLine (c); c = skipWhite (c); } /* Skip `define */ else if (localToken->kind == K_DEFINE) { c = skipWhite (c); c = processDefine (localToken, c); } /* return macro expansion */ else { swapToken (token, localToken); c = skipWhite (c); if (c == '(') c = skipPastMatch ("()"); break; } } deleteToken (localToken); return c; } static void _updateKind (tokenInfo *const token) { verilogKind kind = (verilogKind) lookupKeyword (vStringValue (token->name), getInputLanguage () ); token->kind = ((kind == K_UNDEFINED) && isIdentifier (token)) ? K_IDENTIFIER : kind; } /* read an identifier, keyword, number, compiler directive, or macro identifier */ static int _readWordToken (tokenInfo *const token, int c, bool skip) { Assert (isWordToken (c)); clearToken (token); do { vStringPut (token->name, c); c = vGetc (); } while (isIdentifierCharacter (c)); _updateKind (token); if (skip) return skipWhite (c); else return c; } // read a word token starting with "c". // returns the first charactor of the next token. static int readWordToken (tokenInfo *const token, int c) { return _readWordToken (token, c, true); } // read a word token starting with "c". // returns the next charactor of the token read. // for compiler directives. Since they are line-based, skipWhite() cannot be used. static int readWordTokenNoSkip (tokenInfo *const token, int c) { return _readWordToken (token, c, false); } /* check if an identifier: * simple_identifier ::= [ a-zA-Z_ ] { [ a-zA-Z0-9_$ ] } */ static bool isIdentifier (tokenInfo* token) { if (token->kind == K_UNDEFINED) { for (int i = 0; i < vStringLength (token->name); i++) { int c = vStringChar (token->name, i); if (i == 0) { if (c == '`' || !isWordToken (c)) return false; } else { if (!isIdentifierCharacter (c)) return false; } } return true; } else return false; } static void createContext (verilogKind kind, vString* const name) { tokenInfo *const scope = newToken (); vStringCopy (scope->name, name); scope->kind = kind; if (scope) { vString *contextName = vStringNew (); /* Determine full context name */ if (currentContext->kind != K_UNDEFINED) { vStringCopy (contextName, currentContext->name); vStringPut (contextName, '.'); } vStringCat (contextName, scope->name); /* Create context */ currentContext = pushToken (currentContext, scope); vStringCopy (currentContext->name, contextName); vStringDelete (contextName); verbose ("Created new context %s (kind %d)\n", vStringValue (currentContext->name), currentContext->kind); } } static void dropContext () { verbose ("Dropping context %s\n", vStringValue (currentContext->name)); currentContext = popToken (currentContext); } /* Drop context, but only if an end token is found */ static int dropEndContext (tokenInfo *const token, int c) { verbose ("current context %s; context kind %0d; nest level %0d\n", vStringValue (currentContext->name), currentContext->kind, currentContext->nestLevel); if ((currentContext->kind == K_COVERGROUP && strcmp (vStringValue (token->name), "endgroup") == 0) || (currentContext->kind == K_IFCLASS && strcmp (vStringValue (token->name), "endclass") == 0)) { dropContext (); c = skipBlockName (token ,c); } else if (currentContext->kind != K_UNDEFINED) { vString *endTokenName = vStringNewInit ("end"); vStringCatS (endTokenName, getNameForKind (currentContext->kind)); if (strcmp (vStringValue (token->name), vStringValue (endTokenName)) == 0) { dropContext (); c = skipBlockName (token ,c); if (currentContext->classScope) { verbose ("Dropping local context %s\n", vStringValue (currentContext->name)); currentContext = popToken (currentContext); } } vStringDelete (endTokenName); } else verbose ("Unexpected current context %s\n", vStringValue (currentContext->name)); return c; } static void createTag (tokenInfo *const token, verilogKind kind) { tagEntryInfo tag; if (kind == K_LOCALPARAM) kind = K_CONSTANT; else if (kind == K_PARAMETER) { kind = K_CONSTANT; // See LRM 2017 6.20.1 Parameter declaration syntax if (currentContext->kind != K_CLASS && currentContext->kind != K_PACKAGE && !currentContext->hasParamList) token->parameter = true; } Assert (kind >= 0 && kind != K_UNDEFINED && kind != K_IDENTIFIER); Assert (vStringLength (token->name) > 0); /* check if a container before kind is modified by prototype */ /* BTW should we create a context for a prototype? */ bool container = isContainer (kind); /* Determine if kind is prototype */ if (currentContext->prototype) kind = K_PROTOTYPE; /* Do nothing if tag kind is disabled */ if (! kindEnabled (kind)) { verbose ("kind disabled\n"); return; } /* Create tag */ initTagEntry (&tag, vStringValue (token->name), kind); tag.lineNumber = token->lineNumber; tag.filePosition = token->filePosition; verbose ("Adding tag %s (kind %d)", vStringValue (token->name), kind); if (currentContext->kind != K_UNDEFINED) { verbose (" to context %s\n", vStringValue (currentContext->name)); currentContext->lastKind = kind; tag.extensionFields.scopeKindIndex = currentContext->kind; tag.extensionFields.scopeName = vStringValue (currentContext->name); } verbose ("\n"); if (vStringLength (token->inheritance) > 0) { tag.extensionFields.inheritance = vStringValue (token->inheritance); verbose ("Class %s extends %s\n", vStringValue (token->name), tag.extensionFields.inheritance); } if (token->parameter) attachParserField (&tag, false, fieldTable [F_PARAMETER].ftype, ""); makeTagEntry (&tag); if (isXtagEnabled (XTAG_QUALIFIED_TAGS) && currentContext->kind != K_UNDEFINED) { vString *const scopedName = vStringNew (); vStringCopy (scopedName, currentContext->name); vStringPut (scopedName, '.'); vStringCat (scopedName, token->name); tag.name = vStringValue (scopedName); markTagExtraBit (&tag, XTAG_QUALIFIED_TAGS); makeTagEntry (&tag); vStringDelete (scopedName); } /* Push token as context if it is a container */ if (container) { createContext (kind, token->name); /* Put found contents in context */ verbose ("Putting tagContents: %d element(s)\n", ptrArrayCount (tagContents)); for (unsigned int i = 0; i < ptrArrayCount (tagContents); i++) { tokenInfo *content = ptrArrayItem (tagContents, i); createTag (content, content->kind); } /* Drop temporary contexts */ if (isTempContext (currentContext)) dropContext (); } /* Clear no longer required inheritance information */ vStringClear (token->inheritance); } static int skipBlockName (tokenInfo *const token, int c) { if (c == ':') { c = skipWhite (vGetc ()); if (isWordToken (c)) c = readWordToken (token, c); } return c; } // begin, fork static int processBlock (tokenInfo *const token, int c) { if (c == ':') // tag an optional block identifier { c = skipWhite (vGetc ()); if (isWordToken (c)) { c = readWordToken (token, c); verbose ("Found block: %s\n", vStringValue (token->name)); createTag (token, K_BLOCK); verbose ("Current context %s\n", vStringValue (currentContext->name)); } } currentContext->nestLevel++; // increment after creating a context return c; } // end, join, join_any, join_none static int processEnd (tokenInfo *const token, int c) { if (currentContext->nestLevel > 0) // for sanity check currentContext->nestLevel--; if (currentContext->kind == K_BLOCK && currentContext->nestLevel == 0) dropContext (); c = skipBlockName (token, c); return c; } static int processPortList (tokenInfo *token, int c, bool mayPortDecl) { if (c == '(') { c = skipWhite (vGetc ()); // skip '(' c = tagIdentifierList (token, c, K_PORT, mayPortDecl); if (c == ')') // sanity check c = skipWhite (vGetc ()); else verbose ("Unexpected input: %c\n", c); } return c; } static int skipParameterAssignment (int c) { if (c == '#') { c = skipWhite (vGetc ()); if (c == '(') c = skipPastMatch ("()"); } return c; } // Functions are treated differently because they may also include the type of the return value. // Tasks are treated in the same way, although not having a return value. // // function [ lifetime ] function_data_type_or_implicit [ interface_identifier . | class_scope ] function_identifier [ ( [ tf_port_list ] ) ] ; // task [ lifetime ] task_body_declaration [ interface_identifier . | class_scope ] task_identifier [ ( [ tf_port_list ] ) ] ; static int processFunction (tokenInfo *const token, int c) { verilogKind kind = token->kind; // K_FUNCTION or K_TASK /* Search for function name * Last identifier found before a '(' or a ';' is the function name */ while (c != '(' && c != ';' && c != EOF) { if (isWordToken (c)) c = readWordToken (token, c); else c = skipWhite (vGetc ()); /* skip parameter assignment of a class type * ex. function uvm_port_base #(IF) get_if(int index=0); */ c = skipParameterAssignment (c); /* Identify class type prefixes and create respective context*/ if (isInputLanguage (Lang_systemverilog) && c == ':') { c = vGetc (); if (c == ':') { verbose ("Found function declaration with class type %s\n", vStringValue (token->name)); createContext (K_CLASS, token->name); currentContext->classScope = true; } else vUngetc (c); } } verbose ("Found function: %s\n", vStringValue (token->name)); createTag (token, kind); /* Get port list from function */ c = skipWhite (c); c = processPortList (token, c, false); return c; } // ( enum | union ) [ enum_base_type ] { < enum_name_declaration > } { [ ... ] } static int processEnum (tokenInfo *const token, int c) { tokenInfo* enumToken = dupToken (token); // save enum token /* skip enum_base_type */ while (isWordToken (c)) c = readWordToken (token, c); c = skipDimension (c); /* Search enum elements */ c = pushEnumNames (token, c); /* Skip bus width definition */ c = skipDimension (c); /* Following identifiers are tag names */ verbose ("Find enum tags. Token %s kind %d\n", vStringValue (enumToken->name), enumToken->kind); c = tagNameList (enumToken, c, enumToken->kind); deleteToken (enumToken); // Clean up the tag content list at the end of the declaration to support multiple variables // enum { ... } foo, bar; ptrArrayClear (tagContents); return c; } // [ struct | union [ tagged ] ] [ packed [ signed | unsigned ] ] { struct_union_member { struct_union_member } } { [ ... ] } static int processStruct (tokenInfo *const token, int c) { verilogKind kind = token->kind; // K_STRUCT, K_TYPEDEF, or K_NETTYPE /* Skip packed, signed, and unsigned */ while (isWordToken (c)) c = readWordToken (token, c); /* create a list of members */ c = pushMembers (token, c); /* Skip packed_dimension */ c = skipDimension (c); /* Following identifiers are tag names */ verbose ("Find struct|union tags. Token %s kind %d\n", vStringValue (token->name), token->kind); c = tagNameList (token, c, kind); ptrArrayClear (tagContents); return c; } // data_declaration ::= // [ const ] [ var ] [ static | automatic ] data_type_or_implicit list_of_variable_decl_assignments ; // | typedef data_type type_identifier { [ ... ] } ; // | typedef interface_instance_identifier [ ... ] . type_identifier type_identifier ; // interface based typedef // | typedef [ enum | struct | union | class | interface class ] type_identifier ; // | import < package_import_item > ; // | nettype data_type net_type_identifier [ with [ class_type :: | package_identifier :: | $unit :: ] tf_identifier ] ; // | nettype [ class_type :: | package_identifier :: | $unit :: ] net_type_identifier net_type_identifier ; static int processTypedef (tokenInfo *const token, int c) { verilogKind kindSave = token->kind; // K_TYPEDEF or K_NETTYPE verilogKind kind = K_UNDEFINED; bool not_used; if (isWordToken (c)) { c = readWordToken (token, c); kind = token->kind; } // forward typedef (LRM 6.18) is tagged as prototype // (I don't know why...) switch (kind) { case K_CLASS: case K_INTERFACE: currentContext->prototype = true; break; case K_ENUM: case K_STRUCT: if (isWordToken (c)) { c = readWordToken (token, c); if (token->kind == K_IDENTIFIER && c == ';') currentContext->prototype = true; } break; case K_IDENTIFIER: // interface based typedef c = skipDimension (c); if (c == '.') { c = skipWhite (vGetc ()); if (isWordToken (c)) c = readWordToken (token, c); } if (c == ';') currentContext->prototype = true; break; default: ; // do nothing } c = processType (token, c, &kind, ¬_used); createTag (token, kindSave); ptrArrayClear (tagContents); return c; } static int processParameterList (tokenInfo *token, int c) { bool parameter = true; // default "parameter" if (c != '#') return c; c = skipWhite (vGetc ()); if (c != '(') return c; c = skipWhite (vGetc ()); while (c != ')' && c != EOF) { if (isWordToken (c)) { c = readWordToken (token, c); verbose ("Found parameter %s\n", vStringValue (token->name)); if (token->kind == K_IDENTIFIER) { if (c == ',' || c == ')' || c == '=') // ignore user defined type { tokenInfo *param = dupToken (token); param->kind = K_CONSTANT; param->parameter = parameter; ptrArrayAdd (tagContents, param); if (c == '=') c = skipExpression (vGetc ()); else if (c == ',') c = skipWhite (vGetc ()); else // ')' break; } } else if (token->kind == K_PARAMETER) parameter = true; else if (token->kind == K_LOCALPARAM) parameter = false; } else c = skipWhite (vGetc ()); // unpacked array is not allowed for a parameter } c = skipWhite (vGetc ()); // skip ')' return c; } // [ virtual ] class [ static | automatic ] class_identifier [ parameter_port_list ] // [ extends class_type [ ( list_of_arguments ) ] ] [ implements < interface_class_type > ] ; // interface class class_identifier [ parameter_port_list ] [ extends < interface_class_type > ] ; static int processClass (tokenInfo *const token, int c, verilogKind kind) { tokenInfo *classToken; /* Get identifiers */ while (isWordToken (c)) { c = readWordToken (token, c); // skip static or automatic if (token->kind != K_IGNORE) break; } if (token->kind != K_IDENTIFIER) { verbose ("Unexpected input: class name is expected.\n"); return c; } /* save token */ classToken = dupToken (token); /* Find class parameters list */ c = processParameterList (token, c); /* Search for inheritance information */ if (isWordToken (c)) { c = readWordToken (token, c); if (strcmp (vStringValue (token->name), "extends") == 0) { if (isWordToken (c)) c = readWordToken (token, c); vStringCopy (classToken->inheritance, token->name); verbose ("Inheritance %s\n", vStringValue (classToken->inheritance)); } } // process implements: FIXME createTag (classToken, kind); deleteToken (classToken); ptrArrayClear (tagContents); return c; } // constraint_declaration ::= [ static ] constraint constraint_identifier '{' { constraint_block_item } '}' // constraint_prototype ::= [ extern | pure ] [ static ] constraint constraint_identifier ; static int processConstraint (tokenInfo *const token, int c) { verilogKind kind; if (isWordToken (c)) c = readWordToken (token, c); if (c == '{') { c = skipPastMatch ("{}"); kind = K_CONSTRAINT; } else kind = K_PROTOTYPE; createTag (token, kind); return c; } static int processDefine (tokenInfo *const token, int c) { /* Bug #961001: Verilog compiler directives are line-based. */ if (isWordToken (c)) { c = readWordTokenNoSkip (token, c); createTag (token, K_CONSTANT); } c = skipToNewLine (c); c = skipWhite (c); return c; } // immediate_assertion_statement ::= // ( assert | asume | cover ) [ #0 | final ] '(' expression ')' block // concurrent_assertion_statement ::= // ( assert | assume ) property ( property_spec ) action_block // | expect ( property_spec ) action_block # ignore : processed as same as "if" // | cover property ( property_spec ) statement_or_null // | cover sequence ( [clocking_event ] [ disable iff ( expression_or_dist ) ] sequence_expr ) statement_or_null // | restrict property ( property_spec ) ; static int processAssertion (tokenInfo *const token, int c) { if (vStringLength (currentContext->blockName) > 0) { vStringCopy (token->name, currentContext->blockName); vStringClear (currentContext->blockName); // clear block name not to be reused createTag (token, K_ASSERTION); } // skip final | property | sequence if (isWordToken (c)) c = readWordToken (token, c); // skip #0 c = skipDelay (token, c); // skip ( ... ) if (c == '(') c = skipPastMatch ("()"); return c; } // non-ANSI type // ( module | interface | program ) [ static | automatic ] identifier { package_import_declaration } [ parameter_port_list ] ( port { , port } ) ; // ANSI type // ( module | interface | program ) [ static | automatic ] identifier { package_import_declaration } [ parameter_port_list ] [ ( [ < { (* ... *) } ansi_port_declaration > ] ) ] ; // // interface class class_identifier [ parameter_port_list ] [ extends < interface_class_type > ] ; static int processDesignElementL (tokenInfo *const token, int c) { verilogKind kind = token->kind; while (isWordToken (c)) { c = readWordToken (token, c); // interface class if (token->kind == K_CLASS) return processClass (token, c, K_IFCLASS); // skip static or automatic else if (token->kind != K_IGNORE) break; } if (token->kind == K_IDENTIFIER) createTag (token, kind); // identifier // skip package_import_declaration while (isWordToken (c)) { c = readWordToken (token, c); if (token->kind == K_IMPORT) { c = skipToSemiColon (c); c = skipWhite (vGetc ()); // skip semicolon } else { verbose ("Unexpected input\n"); return c; } } if (c == '#') // parameter_port_list { c = processParameterList (token, c); /* Put found parameters in context */ verbose ("Putting parameters: %d element(s)\n", ptrArrayCount (tagContents)); for (unsigned int i = 0; i < ptrArrayCount (tagContents); i++) { tokenInfo *content = ptrArrayItem (tagContents, i); createTag (content, K_CONSTANT); } ptrArrayClear (tagContents); // disable parameter property on parameter declaration statement currentContext->hasParamList = true; } // Process ANSI/non-ANSI port list in main loop c = processPortList (token, c, true); return c; } // ( checker | property | sequence ) identifier [ ( [ port_list ] ) ] ; // covergroup identifier [ ( [ port_list ] ) ] [ coverage_event ] ; // coverage_event ::= clocking_event | with function sample ( ... ) | @@( ... ) // package identifier ; // modport < identifier ( < ports_declaration > ) > ; // [ default | global ] clocking [ identifier ] ( @ identifier | @ ( event_expression ) ) static int processDesignElementS (tokenInfo *const token, int c) { verilogKind kind = token->kind; if (isWordToken (c)) c = readWordToken (token, c); else return c; createTag (token, kind); // identifier /* Get port list if required */ if (c == '(') // port_list { if (kind == K_MODPORT) c = skipPastMatch ("()"); // ignore port list else c = processPortList (token, c, false); } // skip clocking_event for clocking block or coverage_event for covergroup // "with function sample ()" is processed in the main loop if (c == '@') c = skipClockEvent (token, c); return c; } static int skipDelay (tokenInfo* token, int c) { if (c == '#') { c = skipWhite (vGetc ()); if (c == '(') c = skipPastMatch ("()"); else if (c == '#') // a dirty hack for "x ##delay1 y[*min:max];" c = skipToSemiColon (vGetc ()); else // time literals { while (isIdentifierCharacter (c) || c == '.') c = vGetc (); c = skipWhite (c); } } return c; } static int skipClockEvent (tokenInfo* token, int c) { if (c == '@') { c = skipWhite (vGetc ()); // for @@ ( ... ) : coverage_event if (c == '@') c = skipWhite (vGetc ()); if (c == '(') c = skipPastMatch ("()"); else if (isWordToken (c)) c = readWordToken (token, c); } return c; } static int pushEnumNames (tokenInfo* token, int c) { if (c == '{') { c = skipWhite (vGetc ()); while (c != '}' && c != EOF) { if (!isWordToken (c)) { verbose ("Unexpected input: %c\n", c); return c; } c = readWordToken (token, c); token->kind = K_CONSTANT; ptrArrayAdd (tagContents, dupToken (token)); verbose ("Pushed enum element \"%s\"\n", vStringValue (token->name)); /* Skip element ranges */ /* TODO Implement element ranges */ c = skipDimension (c); /* Skip value assignments */ if (c == '=') c = skipExpression (vGetc ()); /* Skip comma */ if (c == ',') c = skipWhite (vGetc ()); } c = skipWhite (vGetc ()); // skip '}' } return c; } // create a list of struct/union members static int pushMembers (tokenInfo* token, int c) { if (c == '{') { c = skipWhite (vGetc ()); while (c != '}' && c != EOF) { verilogKind kind = K_UNDEFINED; // set kind of context for processType() bool not_used; if (!isWordToken (c)) { verbose ("Unexpected input: %c\n", c); return c; } c = readWordToken (token, c); c = processType (token, c, &kind, ¬_used); while (true) { token->kind = K_MEMBER; ptrArrayAdd (tagContents, dupToken (token)); verbose ("Pushed struct/union member \"%s\"\n", vStringValue (token->name)); /* Skip unpacked dimensions */ c = skipDimension (c); /* Skip value assignments */ if (c == '=') c = skipExpression (vGetc ()); if (c != ',' || c == EOF) break; // should be ';' c = skipWhite (vGetc ()); // skip ',' if (isWordToken (c)) c = readWordToken (token, c); else { verbose ("Unexpected input.\n"); break; } } /* Skip semicolon */ if (c == ';') c = skipWhite (vGetc ()); /* End of enum elements list */ } c = skipWhite (vGetc ()); // skip '}' } return c; } // input // kind: kind of context // output // kind: kind of type // token: identifier token (unless K_IDENTIFIER nor K_UNDEFINED) static int processType (tokenInfo* token, int c, verilogKind* kind, bool* with) { verilogKind actualKind = K_UNDEFINED; tokenInfo *tokenSaved; *with = false; do { c = skipDimension (c); c = skipDelay (token, c); // class parameter #(...) if (c == '{') // skip enum, struct, or union member { if (*kind == K_ENUM) c = pushEnumNames (token, c); else if (*kind == K_STRUCT) c = pushMembers (token, c); else // for a nested structure c = skipPastMatch ("{}"); } c = skipDimension (c); c = skipMacro (c, token); // break on ',', ';', ')', '}', or other unexpected charactors if (!isWordToken (c)) break; tokenSaved = dupToken (token); c = readWordToken (token, c); // break on "with" if (token->kind == K_WITH) { swapToken (token, tokenSaved); deleteToken (tokenSaved); *with = true; // inform to caller break; } deleteToken (tokenSaved); // fix kind of user defined type if (*kind == K_IDENTIFIER) { if (token->kind == K_NET) actualKind = K_NET; else if (token->kind == K_REGISTER) actualKind = K_REGISTER; else if (token->kind == K_PORT) actualKind = K_PORT; else if (token->kind == K_IDENTIFIER) { // identifier of a user defined type *kind = K_REGISTER; // FIXME: consider kind of the user defined type break; } else { verbose ("Unexpected input\n"); // FIXME: x dist {}, with break; } } } while (c != '`' && c != EOF); // break on compiler directive // skip unpacked dimension (or packed dimension after type-words) c = skipDimension (skipWhite (c)); if (*kind == K_UNDEFINED && *kind != K_PORT) *kind = actualKind; return c; } // class_type ::= // ps_class_identifier [ # ( ... ) ] { :: class_identifier [ # ( ... ) ] } // "interface_identifier ." is also handled static int skipClassType (tokenInfo* token, int c) { while (c == '#' || c == ':' || c == '.') { if (c == '#') { c = skipWhite (vGetc ()); // a dirty hack for "x ##delay1 y[*min:max];" if (c == '#') return skipToSemiColon (vGetc ()); c = skipPastMatch ("()"); } else if (c == ':') { c = skipWhite (vGetc ()); if (c != ':') { verbose ("Unexpected input.\n"); vUngetc (c); return ':'; } c = skipWhite (vGetc ()); if (isWordToken (c)) c = readWordToken (token, c); } else // c == '.' : interface_identifier . { c = skipWhite (vGetc ()); if (isWordToken (c)) c = readWordToken (token, c); } } return c; } // Tag a list of identifiers // data_type :: = // ... // | virtual [ interface ] identifier [ # ( [ ... ] ) ] [ . identifier ] // | [ class_type :: | identifier :: | $unit :: ] identifier { [ ... ] } // | [ identifier :: | $unit :: ] identifier [ # ( ... ) ] { :: identifier [ # ( ... ) ] } // | ... // // mayPortDecl: may be a ANSI port declaration. true for module, interface, or program. static int tagIdentifierList (tokenInfo *const token, int c, verilogKind kind, bool mayPortDecl) { bool first_port = true; bool enableTag = true; verilogKind localKind; bool not_used; while (c != ')' && c != EOF) // skip empty port, "()" { // skip attribute_instance: (* ... *) if (c == '(') c = skipPastMatch ("()"); // skip port direction, "virtual", or "interface" while (isWordToken (c)) { c = readWordToken (token, c); if (token->kind == K_PORT || token->kind == K_IGNORE || token->kind == K_INTERFACE) mayPortDecl = false; // now never be a non-ANSI port else break; } if (token->kind == K_IDENTIFIER) c = skipClassType (token, c); c = skipMacro (c, token); // `ifdef, `else, `endif, etc. (between identifiers) if (isWordToken (c)) { c = readWordToken (token, c); if (token->kind == K_IDENTIFIER) { mayPortDecl = false; c = skipClassType (token, c); } } // aoid tagging enum and struct items localKind = token->kind == K_ENUM || token->kind == K_STRUCT ? K_PORT : token->kind; c = processType (token, c, &localKind, ¬_used); // LRM 23.2.2.3 Rules for determining port kind, data type, and direction // If the direction, port kind, and data type are all omitted for // the first port in the port list, ... non-ANSI style, ... if (mayPortDecl && first_port) { first_port = false; if (localKind == K_IDENTIFIER) enableTag = false; // don't tag for non-ANSI port } if (enableTag && token->kind == K_IDENTIFIER) createTag (token, kind); if (c == '=') c = skipExpression (vGetc ()); c = skipMacro (c, token); // `ifdef, `else, `endif, etc. (before comma) if (c != ',' || c == EOF) break; c = skipWhite (vGetc ()); // skip ',' c = skipMacro (c, token); // `ifdef, `else, `endif, etc. (after comma) } return c; } static int tagNameList (tokenInfo* token, int c, verilogKind kind) { c = skipClassType (token, c); if (c == ':' || c == ';') // ## (cycle delay) or unexpected input return c; // skip drive|charge strength or type_reference, dimensions, and delay for net if (c == '(') c = skipPastMatch ("()"); c = skipDimension (c); if (c == '.') return c; // foo[...].bar = ..; c = skipDelay (token, c); while (c != EOF) { bool with = false; c = processType (token, c, &kind, &with); // update token and kind if (c == '=' || c == ',' || c == ';' || c == ')' || c == '`' || with) { // ignore an empty token or procedual assignment: foo = bar; if (kind != K_UNDEFINED && kind != K_IDENTIFIER && token->kind != K_UNDEFINED) createTag (token, kind); if (c == '=') c = skipExpression (c); } else if (c == '(' || c == '[') // should be instance { c = skipDimension (c); // name_of_instance {unpacked_dimension} c = skipPastMatch ("()"); // list_of_port_connections // if without the next "if" clause, get a instance named: `add_t from the following example // var `add_t(foo) = '0; if (c == ';' || c == ',') { verbose ("find instance: %s with kind %s\n", vStringValue (token->name), getNameForKind (K_INSTANCE)); createTag (token, K_INSTANCE); } } c = skipMacro (c, token); // `ifdef, `else, `endif, etc. (before comma) if (c != ',' || c == EOF) break; c = skipWhite (vGetc ()); // skip ',' c = skipMacro (c, token); // `ifdef, `else, `endif, etc. (after comma) } return c; } static int findTag (tokenInfo *const token, int c) { verbose ("Checking token %s of kind %d\n", vStringValue (token->name), token->kind); switch (token->kind) { case K_CONSTANT: case K_EVENT: case K_LOCALPARAM: case K_NET: case K_PARAMETER: case K_PORT: case K_REGISTER: if (token->kind == K_PORT && currentContext->kind == K_CLOCKING) c = skipToSemiColon (c); // clocking items are not port definitions else c = tagNameList (token, c, token->kind); break; case K_IDENTIFIER: { if (c == '[') // for a case label foo[x]: c = skipPastMatch ("[]"); if (c == ':') ; /* label */ else if (c == ',' || c == '{') // "foo, ..." or "coverpoint foo { ... }" c = skipWhite (vGetc ()); else if (c == '(') // task, function, or method call c = skipPastMatch ("()"); else if (c == '=') // assignment c = skipExpression (skipWhite (vGetc ())); else c = tagNameList (token, c, token->kind); /* user defined type */ } break; case K_CLASS: c = processClass (token, c, K_CLASS); break; case K_TYPEDEF: case K_NETTYPE: c = processTypedef (token, c); break; case K_ENUM: c = processEnum (token, c); break; case K_STRUCT: c = processStruct (token, c); break; case K_PROTOTYPE: case K_IMPORT: case K_WITH: currentContext->prototype = true; break; case K_INTERFACE: case K_MODULE: case K_PROGRAM: c = processDesignElementL (token, c); break; case K_CHECKER: case K_CLOCKING: case K_COVERGROUP: case K_MODPORT: case K_PACKAGE: case K_PROPERTY: case K_SEQUENCE: c = processDesignElementS (token, c); break; case K_END_DE: c = dropEndContext (token, c); break; case K_BLOCK: c = processBlock (token, c); break; case K_END: c = processEnd (token, c); break; case K_FUNCTION: case K_TASK: c = processFunction (token, c); break; case K_ASSERTION: c = processAssertion (token, c); break; case K_CONSTRAINT: c = processConstraint (token, c); break; case K_DEFINE: c = processDefine (token, c); break; case K_IGNORE: break; default: verbose ("Unexpected kind->token %d\n", token->kind); } return c; } static void findVerilogTags (void) { tokenInfo *const token = newToken (); int c = skipWhite (vGetc ()); currentContext = newToken (); fieldTable = isInputLanguage (Lang_verilog) ? VerilogFields : SystemVerilogFields; ptrArrayClear (tagContents); while (c != EOF) { switch (c) { case ':': /* Store current block name whenever a : is found * This is used later by any tag type that requires this information */ vStringCopy (currentContext->blockName, token->name); c = skipWhite (vGetc ()); break; case ';': /* Drop context on prototypes because they don't have an * end statement */ if (currentContext->scope && currentContext->scope->prototype) dropContext (); /* Prototypes end at the end of statement */ currentContext->prototype = false; c = skipWhite (vGetc ()); break; case '(': // ignore locally declared variables in a for-loop (LRM 12.7.1) c = skipPastMatch ("()");; break; case '{': c = skipPastMatch ("{}");; break; case '#': c = skipDelay (token, c); break; case '@': c = skipClockEvent (token, c); break; case '"': c = skipString (c); break; default : if (isWordToken (c)) { c = readWordTokenNoSkip (token, c); if (token->kind == K_DIRECTIVE) { // Skip compiler directives which are line-based. c = skipToNewLine (c); c = skipWhite (c); } else if (token->kind != K_UNDEFINED) c = findTag (token, skipWhite (c)); } else c = skipWhite (vGetc ()); } } deleteToken (token); pruneTokens (currentContext); currentContext = NULL; } extern parserDefinition* VerilogParser (void) { static const char *const extensions [] = { "v", NULL }; parserDefinition* def = parserNew ("Verilog"); def->kindTable = VerilogKinds; def->kindCount = ARRAY_SIZE (VerilogKinds); def->fieldTable = VerilogFields; def->fieldCount = ARRAY_SIZE (VerilogFields); def->extensions = extensions; def->parser = findVerilogTags; def->initialize = initializeVerilog; return def; } extern parserDefinition* SystemVerilogParser (void) { static const char *const extensions [] = { "sv", "svh", "svi", NULL }; parserDefinition* def = parserNew ("SystemVerilog"); def->kindTable = SystemVerilogKinds; def->kindCount = ARRAY_SIZE (SystemVerilogKinds); def->fieldTable = SystemVerilogFields; def->fieldCount = ARRAY_SIZE (SystemVerilogFields); def->extensions = extensions; def->parser = findVerilogTags; def->initialize = initializeSystemVerilog; return def; } geany-2.0/ctags/parsers/geany_matlab.c0000644000175000017500000000572114514252267014763 00000000000000/* * * Copyright (c) 2000-2001, Darren Hiebert * * This source code is released for free distribution under the terms of the * GNU General Public License. * * This module contains functions for generating tags for Matlab scripts. * The tags 'function' and 'struct' are parsed. * Author Roland Baudin */ /* * INCLUDE FILES */ #include "general.h" /* must always come first */ #include #include "parse.h" #include "routines.h" #include "read.h" #include "vstring.h" /* * DATA DEFINITIONS */ typedef enum { K_FUNCTION, K_STRUCT } MatlabKind; static kindDefinition MatlabKinds [] = { { true, 'f', "function", "Functions" }, { true, 's', "struct", "Structures" }, }; /* * FUNCTION DEFINITIONS */ static void findMatlabTags (void) { vString *name = vStringNew (); const unsigned char *line; const unsigned char *p; while ((line = readLineFromInputFile ()) != NULL) { int i, ic; if (line [0] == '\0' || line [0] == '%') continue; /* search if the line has a comment */ for (ic = 0 ; line [ic] != '\0' && line [ic]!='%' ; ++ic) ; /* function tag */ /* read first word */ for (i = 0 ; line [i] != '\0' && ! isspace (line [i]) ; ++i) ; if (strncmp ((const char *) line, "function", (size_t) 8) == 0 && isspace (line [8])) { const unsigned char *cp = line + i; const unsigned char *ptr = cp; bool eq=false; while (isspace ((int) *cp)) ++cp; /* search for '=' character in the line (ignoring comments) */ while (*ptr != '\0') { if (*ptr == '%') break; if (*ptr == '=') { eq=true; break; } ptr++; } /* '=' was found => get the first word of the line after '=' */ if (eq) { ptr++; while (isspace ((int) *ptr)) ++ptr; while (isalnum ((int) *ptr) || *ptr == '_') { vStringPut (name, (int) *ptr); ++ptr; } } /* '=' was not found => get the first word of the line after "function" */ else { while (isalnum ((int) *cp) || *cp == '_') { vStringPut (name, (int) *cp); ++cp; } } makeSimpleTag (name, K_FUNCTION); vStringClear (name); } /* struct tag */ /* search if the line contains the keyword 'struct' */ p=(const unsigned char*) strstr ((const char*) line, "struct"); /* and avoid the part after the '%' if any */ if ( p != NULL && ic>0 && p < line+ic) { const unsigned char *cp = line; /* get the left most part of the line before '=' */ while (*cp != '\0' && !isspace(*cp) && *cp != '=' ) { vStringPut (name, (int) *cp); ++cp; } makeSimpleTag (name, K_STRUCT); vStringClear (name); } } vStringDelete (name); } extern parserDefinition* MatLabParser (void) { static const char *const extensions [] = { "m", NULL }; parserDefinition* def = parserNew ("Matlab"); def->kindTable = MatlabKinds; def->kindCount = ARRAY_SIZE (MatlabKinds); def->extensions = extensions; def->parser = findMatlabTags; return def; } geany-2.0/ctags/parsers/lua.c0000644000175000017500000001250314514252267013115 00000000000000/* * Copyright (c) 2000-2001, Max Ischenko . * * This source code is released for free distribution under the terms of the * GNU General Public License version 2 or (at your option) any later version. * * This module contains functions for generating tags for Lua language. */ /* * INCLUDE FILES */ #include "general.h" /* must always come first */ #include #include "debug.h" #include "entry.h" #include "parse.h" #include "read.h" #include "routines.h" #include "vstring.h" /* * DATA DEFINITIONS */ typedef enum { K_FUNCTION, K_UNKNOWN, } luaKind; typedef enum { LUA_UNKNOWN_REFERENCED, } luaUnknownRole; static roleDefinition LuaUnknownRoles [] = { { false, "referenced", "referenced somehow" }, }; static kindDefinition LuaKinds [] = { { true, 'f', "function", "functions" }, /* `unknown' is a kind just for making FQ tag for functions. */ { false, 'X', "unknown", "unknown language object", .referenceOnly = true, ATTACH_ROLES(LuaUnknownRoles) }, }; /* * FUNCTION DEFINITIONS */ /* * Helper function. * Returns 1 if line looks like a line of Lua code. * * TODO: Recognize UNIX bang notation. * (Lua treat first line as a comment if it starts with #!) * */ static bool is_a_code_line (const unsigned char *line) { bool result; const unsigned char *p = line; while (isspace ((int) *p)) p++; if (p [0] == '\0') result = false; else if (p [0] == '-' && p [1] == '-') result = false; else result = true; return result; } static bool isLuaIdentifier (char c) { return (bool) !(isspace(c) || c == '(' || c == ')' || c == '=' || c == '.' || c == ':'); } static void set_scope (int child, int parent) { if (parent == CORK_NIL || child == CORK_NIL) return; tagEntryInfo *e = getEntryInCorkQueue (child); if (!e) return; e->extensionFields.scopeIndex = parent; } static void extract_next_token (const char *begin, const char *end_sentinel, vString *name) { if (begin == NULL || end_sentinel == NULL) return; Assert (begin <= end_sentinel); /* Both on '(' */ if (begin == end_sentinel) return; /* Trim prefixed white spaces */ while (isspace ((int) *begin)) begin++; /* Both on '(' */ if (begin == end_sentinel) return; const char *end = end_sentinel - 1; /* Trim suffixed white spaces */ while (isspace ((int) *end)) end--; Assert (begin <= end); int lastCorkIndx = CORK_NIL; for (const char *c = begin; c <= end; ++c) { if (*c == '.' || *c == ':') { int r = makeSimpleRefTag(name, K_UNKNOWN, LUA_UNKNOWN_REFERENCED); set_scope(r, lastCorkIndx); lastCorkIndx = r; /* Do not include module names in function name */ vStringClear (name); } else if (isLuaIdentifier (*c)) vStringPut (name, (int) *c); else { /* An unexpected character is found * between "function" and "(" */ vStringClear (name); return; } } int d = makeSimpleTag (name, K_FUNCTION); set_scope(d, lastCorkIndx); vStringClear (name); } static void extract_prev_token (const char *end, const char *begin_sentinel, vString *name) { const char *begin; if (end == NULL || begin_sentinel == NULL) return; if (! (begin_sentinel <= end)) return; while (isspace ((int) *end)) { end--; if (! (begin_sentinel <= end)) return; } begin = end; while (begin_sentinel <= begin && isLuaIdentifier (*begin)) begin--; int targetCorkIndex = CORK_NIL; if (end - begin) { vStringNCatS (name, begin + 1, end - begin); targetCorkIndex = makeSimpleTag (name, K_FUNCTION); vStringClear (name); } if (targetCorkIndex == CORK_NIL || begin_sentinel == begin) return; /* Fill the scope field of the function. */ end = begin; while (begin_sentinel <= (begin + 1)) { bool on_boundary = false; if (begin < begin_sentinel || !isLuaIdentifier (*begin)) { if (end - begin) { vStringNCatS (name, begin + 1, end - begin); int r = makeSimpleRefTag (name, K_UNKNOWN, LUA_UNKNOWN_REFERENCED); set_scope (targetCorkIndex, r); targetCorkIndex = r; vStringClear (name); } if (begin_sentinel <= begin && ! (*begin == ':' || *begin == '.')) break; on_boundary = true; } begin--; if(on_boundary) end = begin; } } static void findLuaTags (void) { vString *name = vStringNew (); const unsigned char *line; while ((line = readLineFromInputFile ()) != NULL) { const char *p, *q; if (! is_a_code_line (line)) continue; p = (const char*) strstr ((const char*) line, "function"); if (p == NULL) continue; q = strchr ((const char*) line, '='); if (q == NULL) { p = p + 8; /* skip the `function' word */ /* We expect [ \t(] */ if (! (*p == '(' || isspace ((int)*p))) continue; q = strchr ((const char*) p, '('); if (q) extract_next_token (p, q, name); } else if ( (*(q+1) != '=') /* ignore `if type(v) == "function" then ...' */ && (q < p) /* ignore "function" ~= */ ) { p = (const char*) &line[0]; if (p < q) extract_prev_token (q - 1, p, name); } } vStringDelete (name); } extern parserDefinition* LuaParser (void) { static const char* const extensions [] = { "lua", NULL }; parserDefinition* def = parserNew ("Lua"); def->kindTable = LuaKinds; def->kindCount = ARRAY_SIZE (LuaKinds); def->extensions = extensions; def->parser = findLuaTags; def->useCork = CORK_QUEUE; def->requestAutomaticFQTag = true; return def; } geany-2.0/ctags/parsers/pascal.c0000644000175000017500000001756314514252267013612 00000000000000/* * Copyright (c) 2001-2002, Darren Hiebert * * This source code is released for free distribution under the terms of the * GNU General Public License version 2 or (at your option) any later version. * * This module contains functions for generating tags for the Pascal language, * including some extensions for Object Pascal. */ /* * INCLUDE FILES */ #include "general.h" /* must always come first */ #include #include "entry.h" #include "parse.h" #include "read.h" #include "routines.h" #include "vstring.h" /* * DATA DEFINITIONS */ typedef enum { K_FUNCTION, K_PROCEDURE } pascalKind; static kindDefinition PascalKinds [] = { { true, 'f', "function", "functions"}, { true, 'p', "procedure", "procedures"} }; /* * FUNCTION DEFINITIONS */ static void createPascalTag ( tagEntryInfo* const tag, const vString* const name, const int kind, const vString *arglist, const vString *vartype) { if (PascalKinds [kind].enabled && name != NULL && vStringLength (name) > 0) { initTagEntry (tag, vStringValue (name), kind); if (arglist && !vStringIsEmpty (arglist)) { tag->extensionFields.signature = vStringValue (arglist); } if (vartype && !vStringIsEmpty (vartype)) { tag->extensionFields.typeRef[0] = "typename"; tag->extensionFields.typeRef[1] = vStringValue (vartype); } } else /* TODO: Passing NULL as name makes an assertion behind initTagEntry failure */ initTagEntry (tag, NULL, KIND_GHOST_INDEX); } static void makePascalTag (const tagEntryInfo* const tag) { if (tag->name != NULL) makeTagEntry (tag); } static const unsigned char* dbp; #define starttoken(c) (isalpha ((int) c) || (int) c == '_') #define intoken(c) (isalnum ((int) c) || (int) c == '_' || (int) c == '.') #define endtoken(c) (! intoken (c) && ! isdigit ((int) c)) static bool tail (const char *cp) { bool result = false; register int len = 0; while (*cp != '\0' && tolower ((int) *cp) == tolower ((int) dbp [len])) cp++, len++; if (*cp == '\0' && !intoken (dbp [len])) { dbp += len; result = true; } return result; } static void parseArglist (const char *buf, vString *arglist, vString *vartype) { const char *start, *end; int level; if (NULL == buf || arglist == NULL) return; /* parse argument list which can be missing like in "function ginit:integer;" */ if (NULL != (start = strchr (buf, '('))) { for (level = 1, end = start + 1; level > 0; ++end) { if ('\0' == *end) break; else if ('(' == *end) ++ level; else if (')' == *end) -- level; } } else /* if no argument list was found, continue looking for a return value */ { start = NULL; end = buf; } /* parse return type if requested by passing a non-NULL vartype argument */ if (NULL != vartype) { char *var, *var_start; if (NULL != (var = strchr (end, ':'))) { var++; /* skip ':' */ while (isspace ((int) *var)) ++var; if (starttoken (*var)) { var_start = var; var++; while (intoken (*var)) var++; if (endtoken (*var)) { vStringNCatS (vartype, var_start, var - var_start); } } } } if (NULL == start) /* no argument list */ vStringCatS (arglist, "()"); else vStringNCatS (arglist, start, end - start); } /* Algorithm adapted from from GNU etags. * Locates tags for procedures & functions. Doesn't do any type- or * var-definitions. It does look for the keyword "extern" or "forward" * immediately following the procedure statement; if found, the tag is * skipped. */ static void findPascalTags (void) { vString *name = vStringNew (); vString *arglist = vStringNew (); vString *vartype = vStringNew (); tagEntryInfo tag; pascalKind kind = K_FUNCTION; /* each of these flags is true iff: */ bool incomment = false; /* point is inside a comment */ int comment_char = '\0'; /* type of current comment */ bool inquote = false; /* point is inside '..' string */ bool get_tagname = false;/* point is after PROCEDURE/FUNCTION keyword, so next item = potential tag */ bool found_tag = false; /* point is after a potential tag */ bool inparms = false; /* point is within parameter-list */ bool verify_tag = false; /* point has passed the parm-list, so the next token will determine * whether this is a FORWARD/EXTERN to be ignored, or whether it is a * real tag */ dbp = readLineFromInputFile (); while (dbp != NULL) { int c = *dbp++; if (c == '\0') /* if end of line */ { dbp = readLineFromInputFile (); if (dbp == NULL || *dbp == '\0') continue; if (!((found_tag && verify_tag) || get_tagname)) c = *dbp++; /* only if don't need *dbp pointing to the beginning of * the name of the procedure or function */ } if (incomment) { if (comment_char == '{' && c == '}') incomment = false; else if (comment_char == '(' && c == '*' && *dbp == ')') { dbp++; incomment = false; } continue; } else if (inquote) { if (c == '\'') inquote = false; continue; } else switch (c) { case '\'': inquote = true; /* found first quote */ continue; case '{': /* found open { comment */ incomment = true; comment_char = c; continue; case '(': if (*dbp == '*') /* found open (* comment */ { incomment = true; comment_char = c; dbp++; } else if (found_tag) /* found '(' after tag, i.e., parm-list */ inparms = true; continue; case ')': /* end of parms list */ if (inparms) inparms = false; continue; case ';': if (found_tag && !inparms) /* end of proc or fn stmt */ { verify_tag = true; break; } continue; } if (found_tag && verify_tag && *dbp != ' ') { /* check if this is an "extern" declaration */ if (*dbp == '\0') continue; if (tolower ((int) *dbp == 'e')) { if (tail ("extern")) /* superfluous, really! */ { found_tag = false; verify_tag = false; } } else if (tolower ((int) *dbp) == 'f') { if (tail ("forward")) /* check for forward reference */ { found_tag = false; verify_tag = false; } } if (found_tag && verify_tag) /* not external proc, so make tag */ { found_tag = false; verify_tag = false; makePascalTag (&tag); continue; } } if (get_tagname) /* grab name of proc or fn */ { const unsigned char *cp; if (*dbp == '\0') continue; /* grab block name */ while (isspace ((int) *dbp)) ++dbp; if (!starttoken(*dbp)) continue; for (cp = dbp ; *cp != '\0' && !endtoken (*cp) ; cp++) continue; vStringNCopyS (name, (const char*) dbp, cp - dbp); vStringClear (arglist); vStringClear (vartype); parseArglist ((const char*) cp, arglist, (kind == K_FUNCTION) ? vartype : NULL); createPascalTag (&tag, name, kind, arglist, (kind == K_FUNCTION) ? vartype : NULL); dbp = cp; /* set dbp to e-o-token */ get_tagname = false; found_tag = true; /* and proceed to check for "extern" */ } else if (!incomment && !inquote && !found_tag) { switch (tolower ((int) c)) { case 'c': if (tail ("onstructor")) { get_tagname = true; kind = K_PROCEDURE; } break; case 'd': if (tail ("estructor")) { get_tagname = true; kind = K_PROCEDURE; } break; case 'p': if (tail ("rocedure")) { get_tagname = true; kind = K_PROCEDURE; } break; case 'f': if (tail ("unction")) { get_tagname = true; kind = K_FUNCTION; } break; } } /* while not eof */ } vStringDelete (arglist); vStringDelete (vartype); vStringDelete (name); } extern parserDefinition* PascalParser (void) { static const char *const extensions [] = { "p", "pas", NULL }; parserDefinition* def = parserNew ("Pascal"); def->extensions = extensions; def->kindTable = PascalKinds; def->kindCount = ARRAY_SIZE (PascalKinds); def->parser = findPascalTags; return def; } geany-2.0/ctags/parsers/tcl.h0000644000175000017500000000242114514252267013121 00000000000000/* * Copyright (c) 2017, Masatake YAMATO * * This source code is released for free distribution under the terms of the * GNU General Public License version 2 or (at your option) any later version. */ #ifndef CTAGS_PARSER_TCL_H #define CTAGS_PARSER_TCL_H /* * INCLUDE FILES */ #include "general.h" /* must always come first */ #include "subparser.h" #include "tokeninfo.h" typedef struct sTclSubparser tclSubparser; enum TclTokenType { /* 0..255 are the byte's value */ TOKEN_TCL_EOF = 256, TOKEN_TCL_UNDEFINED, TOKEN_TCL_KEYWORD, TOKEN_TCL_IDENTIFIER, TOKEN_TCL_VARIABLE, TOKEN_TCL_EOL, TOKEN_TCL_STRING, }; struct sTclSubparser { subparser subparser; /* `pstate' is needed to call newTclToken(). */ void (* namespaceImportNotify) (tclSubparser *s, char *namespace, void *pstate); /* Return CORK_NIL if the command line is NOT consumed. If a positive integer is returned, end: field may be attached by tcl base parser. Return CORK_NIL - 1 if the command line is consumed but not tag is made. */ int (* commandNotify) (tclSubparser *s, char *command, int parentIndex, void *pstate); }; extern tokenInfo *newTclToken (void *pstate); extern void skipToEndOfTclCmdline (tokenInfo *const token); #endif /* CTAGS_PARSER_TCL_H */ geany-2.0/ctags/parsers/php.c0000644000175000017500000013206014514252267013124 00000000000000/* * Copyright (c) 2013, Colomban Wendling * * This source code is released for free distribution under the terms of the * GNU General Public License version 2 or (at your option) any later version. * * This module contains code for generating tags for the PHP scripting * language. * * The language reference: http://php.net/manual/en/langref.php */ /* * INCLUDE FILES */ #include "general.h" /* must always come first */ #include #include "parse.h" #include "read.h" #include "vstring.h" #include "keyword.h" #include "entry.h" #include "routines.h" #include "debug.h" #include "objpool.h" #define isIdentChar(c) (isalnum (c) || (c) == '_' || (c) >= 0x80) #define newToken() (objPoolGet (TokenPool)) #define deleteToken(t) (objPoolPut (TokenPool, (t))) enum { KEYWORD_abstract, KEYWORD_and, KEYWORD_as, KEYWORD_break, KEYWORD_callable, KEYWORD_case, KEYWORD_catch, KEYWORD_class, KEYWORD_clone, KEYWORD_const, KEYWORD_continue, KEYWORD_declare, KEYWORD_define, KEYWORD_default, KEYWORD_do, KEYWORD_echo, KEYWORD_else, KEYWORD_elif, KEYWORD_enddeclare, KEYWORD_endfor, KEYWORD_endforeach, KEYWORD_endif, KEYWORD_endswitch, KEYWORD_endwhile, KEYWORD_extends, KEYWORD_final, KEYWORD_finally, KEYWORD_for, KEYWORD_foreach, KEYWORD_function, KEYWORD_global, KEYWORD_goto, KEYWORD_if, KEYWORD_implements, KEYWORD_include, KEYWORD_include_once, KEYWORD_instanceof, KEYWORD_insteadof, KEYWORD_interface, KEYWORD_namespace, KEYWORD_new, KEYWORD_or, KEYWORD_print, KEYWORD_private, KEYWORD_protected, KEYWORD_public, KEYWORD_require, KEYWORD_require_once, KEYWORD_return, KEYWORD_static, KEYWORD_switch, KEYWORD_throw, KEYWORD_trait, KEYWORD_try, KEYWORD_use, KEYWORD_var, KEYWORD_while, KEYWORD_xor, KEYWORD_yield }; typedef int keywordId; /* to allow KEYWORD_NONE */ typedef enum { ACCESS_UNDEFINED, ACCESS_PRIVATE, ACCESS_PROTECTED, ACCESS_PUBLIC, COUNT_ACCESS } accessType; typedef enum { IMPL_UNDEFINED, IMPL_ABSTRACT, COUNT_IMPL } implType; typedef enum { K_CLASS, K_DEFINE, K_FUNCTION, K_INTERFACE, K_LOCAL_VARIABLE, K_NAMESPACE, K_TRAIT, K_VARIABLE, K_ALIAS, COUNT_KIND } phpKind; #define NAMESPACE_SEPARATOR "\\" static scopeSeparator PhpGenericSeparators [] = { { K_NAMESPACE , NAMESPACE_SEPARATOR }, { KIND_WILDCARD_INDEX, "::" }, }; static kindDefinition PhpKinds[COUNT_KIND] = { { true, 'c', "class", "classes", ATTACH_SEPARATORS(PhpGenericSeparators) }, { true, 'd', "define", "constant definitions", ATTACH_SEPARATORS(PhpGenericSeparators)}, { true, 'f', "function", "functions", ATTACH_SEPARATORS(PhpGenericSeparators)}, { true, 'i', "interface", "interfaces", ATTACH_SEPARATORS(PhpGenericSeparators)}, { false, 'l', "local", "local variables", ATTACH_SEPARATORS(PhpGenericSeparators)}, { true, 'n', "namespace", "namespaces", ATTACH_SEPARATORS(PhpGenericSeparators)}, { true, 't', "trait", "traits", ATTACH_SEPARATORS(PhpGenericSeparators)}, { true, 'v', "variable", "variables", ATTACH_SEPARATORS(PhpGenericSeparators)}, { true, 'a', "alias", "aliases", ATTACH_SEPARATORS(PhpGenericSeparators)}, }; static const keywordTable PhpKeywordTable[] = { /* keyword keyword ID */ { "abstract", KEYWORD_abstract }, { "and", KEYWORD_and }, { "as", KEYWORD_as }, { "break", KEYWORD_break }, { "callable", KEYWORD_callable }, { "case", KEYWORD_case }, { "catch", KEYWORD_catch }, { "cfunction", KEYWORD_function }, /* nobody knows what the hell this is, but it seems to behave much like "function" so bind it to it */ { "class", KEYWORD_class }, { "clone", KEYWORD_clone }, { "const", KEYWORD_const }, { "continue", KEYWORD_continue }, { "declare", KEYWORD_declare }, { "define", KEYWORD_define }, /* this isn't really a keyword but we handle it so it's easier this way */ { "default", KEYWORD_default }, { "do", KEYWORD_do }, { "echo", KEYWORD_echo }, { "else", KEYWORD_else }, { "elseif", KEYWORD_elif }, { "enddeclare", KEYWORD_enddeclare }, { "endfor", KEYWORD_endfor }, { "endforeach", KEYWORD_endforeach }, { "endif", KEYWORD_endif }, { "endswitch", KEYWORD_endswitch }, { "endwhile", KEYWORD_endwhile }, { "extends", KEYWORD_extends }, { "final", KEYWORD_final }, { "finally", KEYWORD_finally }, { "for", KEYWORD_for }, { "foreach", KEYWORD_foreach }, { "function", KEYWORD_function }, { "global", KEYWORD_global }, { "goto", KEYWORD_goto }, { "if", KEYWORD_if }, { "implements", KEYWORD_implements }, { "include", KEYWORD_include }, { "include_once", KEYWORD_include_once }, { "instanceof", KEYWORD_instanceof }, { "insteadof", KEYWORD_insteadof }, { "interface", KEYWORD_interface }, { "namespace", KEYWORD_namespace }, { "new", KEYWORD_new }, { "or", KEYWORD_or }, { "print", KEYWORD_print }, { "private", KEYWORD_private }, { "protected", KEYWORD_protected }, { "public", KEYWORD_public }, { "require", KEYWORD_require }, { "require_once", KEYWORD_require_once }, { "return", KEYWORD_return }, { "static", KEYWORD_static }, { "switch", KEYWORD_switch }, { "throw", KEYWORD_throw }, { "trait", KEYWORD_trait }, { "try", KEYWORD_try }, { "use", KEYWORD_use }, { "var", KEYWORD_var }, { "while", KEYWORD_while }, { "xor", KEYWORD_xor }, { "yield", KEYWORD_yield } }; typedef enum eTokenType { TOKEN_UNDEFINED, TOKEN_EOF, TOKEN_CHARACTER, TOKEN_CLOSE_PAREN, TOKEN_SEMICOLON, TOKEN_COLON, TOKEN_COMMA, TOKEN_KEYWORD, TOKEN_OPEN_PAREN, TOKEN_OPERATOR, TOKEN_IDENTIFIER, TOKEN_STRING, TOKEN_PERIOD, TOKEN_OPEN_CURLY, TOKEN_CLOSE_CURLY, TOKEN_EQUAL_SIGN, TOKEN_OPEN_SQUARE, TOKEN_CLOSE_SQUARE, TOKEN_VARIABLE, TOKEN_AMPERSAND, TOKEN_BACKSLASH, TOKEN_QMARK, } tokenType; typedef struct { tokenType type; keywordId keyword; vString * string; vString * scope; unsigned long lineNumber; MIOPos filePosition; int parentKind; /* -1 if none */ bool anonymous; /* true if token specifies * an anonymous class */ } tokenInfo; static langType Lang_php; static langType Lang_zephir; static bool InPhp = false; /* whether we are between */ /* whether the next token may be a keyword, e.g. not after "::" or "->" */ static bool MayBeKeyword = true; /* current statement details */ static struct { accessType access; implType impl; } CurrentStatement; /* Current namespace */ static vString *CurrentNamesapce; /* Cache variable to build the tag's scope. It has no real meaning outside * of initPhpEntry()'s scope. */ static vString *FullScope; /* The class name specified at "extends" keyword in the current class * definition. Used to resolve "parent" in return type. */ static vString *ParentClass; static objPool *TokenPool = NULL; static const char *phpScopeSeparatorFor (int kind, int upperScopeKind) { return scopeSeparatorFor (getInputLanguage(), kind, upperScopeKind); } static const char *accessToString (const accessType access) { static const char *const names[COUNT_ACCESS] = { "undefined", "private", "protected", "public" }; Assert (access < COUNT_ACCESS); return names[access]; } static const char *implToString (const implType impl) { static const char *const names[COUNT_IMPL] = { "undefined", "abstract" }; Assert (impl < COUNT_IMPL); return names[impl]; } static void initPhpEntry (tagEntryInfo *const e, const tokenInfo *const token, const phpKind kind, const accessType access) { int parentKind = -1; vStringClear (FullScope); if (vStringLength (CurrentNamesapce) > 0) { parentKind = K_NAMESPACE; vStringCat (FullScope, CurrentNamesapce); } initTagEntry (e, vStringValue (token->string), kind); e->lineNumber = token->lineNumber; e->filePosition = token->filePosition; if (access != ACCESS_UNDEFINED) e->extensionFields.access = accessToString (access); if (vStringLength (token->scope) > 0) { parentKind = token->parentKind; if (vStringLength (FullScope) > 0) { const char* sep; sep = phpScopeSeparatorFor (parentKind, K_NAMESPACE); vStringCatS (FullScope, sep); } vStringCat (FullScope, token->scope); } if (vStringLength (FullScope) > 0) { Assert (parentKind >= 0); e->extensionFields.scopeKindIndex = parentKind; e->extensionFields.scopeName = vStringValue (FullScope); } if (token->anonymous) markTagExtraBit (e, XTAG_ANONYMOUS); } static void makePhpTagEntry (tagEntryInfo *const e) { makeTagEntry (e); makeQualifiedTagEntry (e); } static void fillTypeRefField (tagEntryInfo *const e, const vString *const rtype, const tokenInfo *const token) { if ((vStringLength (rtype) == 4) && (strcmp (vStringValue (rtype), "self") == 0) && vStringLength (token->scope) > 0) { if (token->parentKind == -1) e->extensionFields.typeRef [0] = "unknown"; else e->extensionFields.typeRef [0] = PhpKinds [token->parentKind].name; e->extensionFields.typeRef [1] = vStringValue (token->scope); } else if ((vStringLength (rtype) == 6) && (strcmp (vStringValue (rtype), "parent") == 0) && (ParentClass && vStringLength (ParentClass) > 0)) { e->extensionFields.typeRef [0] = "class"; e->extensionFields.typeRef [1] = vStringValue (ParentClass); } else { e->extensionFields.typeRef [0] = "unknown"; e->extensionFields.typeRef [1] = vStringValue (rtype); } } static void makeTypedPhpTag (const tokenInfo *const token, const phpKind kind, const accessType access, vString* typeName) { if (PhpKinds[kind].enabled) { tagEntryInfo e; initPhpEntry (&e, token, kind, access); if (typeName) fillTypeRefField (&e, typeName, token); makePhpTagEntry (&e); } } static void makeSimplePhpTag (const tokenInfo *const token, const phpKind kind, const accessType access) { makeTypedPhpTag (token, kind, access, NULL); } static void makeNamespacePhpTag (const tokenInfo *const token, const vString *const name) { if (PhpKinds[K_NAMESPACE].enabled) { tagEntryInfo e; initTagEntry (&e, vStringValue (name), K_NAMESPACE); e.lineNumber = token->lineNumber; e.filePosition = token->filePosition; makePhpTagEntry (&e); } } static void makeClassOrIfaceTag (const phpKind kind, const tokenInfo *const token, vString *const inheritance, const implType impl) { if (PhpKinds[kind].enabled) { tagEntryInfo e; initPhpEntry (&e, token, kind, ACCESS_UNDEFINED); if (impl != IMPL_UNDEFINED) e.extensionFields.implementation = implToString (impl); if (vStringLength (inheritance) > 0) e.extensionFields.inheritance = vStringValue (inheritance); makePhpTagEntry (&e); } } static void makeFunctionTag (const tokenInfo *const token, const vString *const arglist, const vString *const rtype, const accessType access, const implType impl) { if (PhpKinds[K_FUNCTION].enabled) { tagEntryInfo e; initPhpEntry (&e, token, K_FUNCTION, access); if (impl != IMPL_UNDEFINED) e.extensionFields.implementation = implToString (impl); if (arglist) e.extensionFields.signature = vStringValue (arglist); if (rtype) fillTypeRefField (&e, rtype, token); makePhpTagEntry (&e); } } static void *newPoolToken (void *createArg CTAGS_ATTR_UNUSED) { tokenInfo *token = xMalloc (1, tokenInfo); token->string = vStringNew (); token->scope = vStringNew (); return token; } static void clearPoolToken (void *data) { tokenInfo *token = data; token->type = TOKEN_UNDEFINED; token->keyword = KEYWORD_NONE; token->lineNumber = getInputLineNumber (); token->filePosition = getInputFilePosition (); token->parentKind = -1; token->anonymous = false; vStringClear (token->string); vStringClear (token->scope); } static void deletePoolToken (void *data) { tokenInfo *token = data; vStringDelete (token->string); vStringDelete (token->scope); eFree (token); } static void copyToken (tokenInfo *const dest, const tokenInfo *const src, bool scope) { dest->lineNumber = src->lineNumber; dest->filePosition = src->filePosition; dest->type = src->type; dest->keyword = src->keyword; vStringCopy(dest->string, src->string); dest->parentKind = src->parentKind; if (scope) vStringCopy(dest->scope, src->scope); dest->anonymous = src->anonymous; } #if 0 #include static const char *tokenTypeName (const tokenType type) { switch (type) { case TOKEN_UNDEFINED: return "undefined"; case TOKEN_EOF: return "EOF"; case TOKEN_CHARACTER: return "character"; case TOKEN_CLOSE_PAREN: return "')'"; case TOKEN_SEMICOLON: return "';'"; case TOKEN_COLON: return "':'"; case TOKEN_COMMA: return "','"; case TOKEN_OPEN_PAREN: return "'('"; case TOKEN_OPERATOR: return "operator"; case TOKEN_IDENTIFIER: return "identifier"; case TOKEN_KEYWORD: return "keyword"; case TOKEN_STRING: return "string"; case TOKEN_PERIOD: return "'.'"; case TOKEN_OPEN_CURLY: return "'{'"; case TOKEN_CLOSE_CURLY: return "'}'"; case TOKEN_EQUAL_SIGN: return "'='"; case TOKEN_OPEN_SQUARE: return "'['"; case TOKEN_CLOSE_SQUARE: return "']'"; case TOKEN_VARIABLE: return "variable"; } return NULL; } static void printToken (const tokenInfo *const token) { fprintf (stderr, "%p:\n\ttype:\t%s\n\tline:\t%lu\n\tscope:\t%s\n", (void *) token, tokenTypeName (token->type), token->lineNumber, vStringValue (token->scope)); switch (token->type) { case TOKEN_IDENTIFIER: case TOKEN_STRING: case TOKEN_VARIABLE: fprintf (stderr, "\tcontent:\t%s\n", vStringValue (token->string)); break; case TOKEN_KEYWORD: { size_t n = ARRAY_SIZE (PhpKeywordTable); size_t i; fprintf (stderr, "\tkeyword:\t"); for (i = 0; i < n; i++) { if (PhpKeywordTable[i].id == token->keyword) { fprintf (stderr, "%s\n", PhpKeywordTable[i].name); break; } } if (i >= n) fprintf (stderr, "(unknown)\n"); } default: break; } } #endif static void addToScope (tokenInfo *const token, const vString *const extra, int kindOfUpperScope) { if (vStringLength (token->scope) > 0) { const char* sep; sep = phpScopeSeparatorFor(token->parentKind, kindOfUpperScope); vStringCatS (token->scope, sep); } vStringCat (token->scope, extra); } static int skipToCharacter (const int c) { int d; do { d = getcFromInputFile (); } while (d != EOF && d != c); return d; } static void parseString (vString *const string, const int delimiter) { while (true) { int c = getcFromInputFile (); if (c == '\\' && (c = getcFromInputFile ()) != EOF) vStringPut (string, (char) c); else if (c == EOF || c == delimiter) break; else vStringPut (string, (char) c); } } /* Strips @indent_len characters from lines in @string to get the correct * string value for an indented heredoc (PHP 7.3+). * This doesn't handle invalid values specially and might yield surprising * results with them, but it doesn't really matter as it's invalid anyway. */ static void stripHeredocIndent (vString *const string, size_t indent_len) { char *str = vStringValue (string); size_t str_len = vStringLength (string); char *p = str; size_t new_len = str_len; bool at_line_start = true; while (*p) { if (at_line_start) { size_t p_len; size_t strip_len; p_len = str_len - (p - str); strip_len = p_len < indent_len ? p_len : indent_len; memmove (p, p + strip_len, p_len - strip_len); p += strip_len; new_len -= strip_len; } /* CRLF is already normalized as LF */ at_line_start = (*p == '\r' || *p == '\n'); p++; } vStringTruncate (string, new_len); } /* reads a PHP >= 7.3 HereDoc or a NowDoc (the part after the <<<). * <<<[ \t]*(ID|'ID'|"ID") * ... * [ \t]*ID[^:indent-char:];? * * note that: * 1) starting ID must be immediately followed by a newline; * 2) closing ID is the same as opening one; * 3) closing ID must not be immediately followed by an identifier character; * 4) optional indentation of the closing ID is stripped from body lines, * which lines must have the exact same prefix indentation. * * This is slightly relaxed from PHP < 7.3, where the closing ID had to be the * only thing on its line, with the only exception of a semicolon right after * the ID. * * Example of a single valid heredoc: * <<< FOO * something * something else * FOO_this is not an end * FOO; * # previous line was the end, but the semicolon wasn't required * * Another example using indentation and more code after the heredoc: * << 0) stripHeredocIndent (string, indent_len); break; } /* if we are here it wasn't a delimiter, so put everything in the * string */ vStringNCatS (string, delimiter, len); } } while (c != EOF); return; error: ungetcToInputFile (c); } static void parseIdentifier (vString *const string, const int firstChar) { int c = firstChar; do { vStringPut (string, (char) c); c = getcFromInputFile (); } while (isIdentChar (c)); ungetcToInputFile (c); } static bool isSpace (int c) { return (c == '\t' || c == ' ' || c == '\v' || c == '\n' || c == '\r' || c == '\f'); } static int skipWhitespaces (int c) { while (isSpace (c)) c = getcFromInputFile (); return c; } /* * * This is ugly, but the whole "