emacs-orgmode
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [O] How to make a non-GPL Org-mode exporter?


From: Oleh Krehel
Subject: Re: [O] How to make a non-GPL Org-mode exporter?
Date: Tue, 28 Jul 2015 12:29:00 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.5 (gnu/linux)

Andreas Hilboll <address@hidden> writes:

>>> However, when the interpreter is extended to provide “bindings” to
>>> other facilities (often, but not necessarily, libraries), the
>>> interpreted program is effectively linked to the facilities it uses
>>> through these bindings. So if these facilities are released under the
>>> GPL, the interpreted program that uses them must be released in a
>>> GPL-compatible way. The JNI or Java Native Interface is an example of
>>> such a binding mechanism; libraries that are accessed in this way are
>>> linked dynamically with the Java programs that call them. These
>>> libraries are also linked with the interpreter. If the interpreter is
>>> linked statically with these libraries, or if it is designed to link
>>> dynamically with these specific libraries, then it too needs to be
>>> released in a GPL-compatible way.
>> 
>> Indeed, the Emacs interpreter gives "bindings" to all Emacs facilities,
>> which are GPL, and the interpreted program that uses them must be
>> released in a GPL-compatible way.
>
> I would interpret this as
>
>    "As long as I write pure elisp and don't require' and GPL'ed part of
>    Emacs, I can release my code under any license I want.  If I do
>    require' any part of Emacs, I have to go the GPL path."
>
> If I'm wrong with this interpretation, please explain why.

Your interpretation is entirely correct. However, to write almost any
useful code, you're going to need to require some parts of
Emacs. Anything that interacts with text in a buffer will need to call
`buffer-string' eventually - GPL-ed code.

Here are the famous 9 lines from the Oracle-Google Java lawsuit:

    private static void rangeCheck(int arrayLen, int fromIndex, int toIndex {
         if (fromIndex > toIndex)
              throw new IllegalArgumentException("fromIndex(" + fromIndex +
                   ") > toIndex(" + toIndex+")");
         if (fromIndex < 0) 
              throw new ArrayIndexOutOfBoundsException(fromIndex);
         if (toIndex > arrayLen) 
              throw new ArrayIndexOutOfBoundsException(toIndex);
    }

This lawsuit is currently on some sort of appeal now. The code above is
essentially the most simple, efficient and obvious way to implement the
rangeCheck function based on the API signature. And still they sued.

On the other hand, the implementation of `buffer-string' isn't at all
trivial:

    DEFUN ("buffer-string", Fbuffer_string, Sbuffer_string, 0, 0, 0,
           doc: /* Return the contents of the current buffer as a string.
    If narrowing is in effect, this function returns only the visible part
    of the buffer.  */)
      (void)
    {
      return make_buffer_string_both (BEGV, BEGV_BYTE, ZV, ZV_BYTE, 1);
    }

    Lisp_Object
    make_buffer_string_both (ptrdiff_t start, ptrdiff_t start_byte,
                         ptrdiff_t end, ptrdiff_t end_byte, bool props)
    {
      Lisp_Object result, tem, tem1;
    
      if (start < GPT && GPT < end)
        move_gap_both (start, start_byte);
    
      if (! NILP (BVAR (current_buffer, enable_multibyte_characters)))
        result = make_uninit_multibyte_string (end - start, end_byte - 
start_byte);
      else
        result = make_uninit_string (end - start);
      memcpy (SDATA (result), BYTE_POS_ADDR (start_byte), end_byte - 
start_byte);
    
      /* If desired, update and copy the text properties.  */
      if (props)
        {
          update_buffer_properties (start, end);
    
          tem = Fnext_property_change (make_number (start), Qnil, make_number 
(end));
          tem1 = Ftext_properties_at (make_number (start), Qnil);
    
          if (XINT (tem) != end || !NILP (tem1))
        copy_intervals_to_string (result, current_buffer, start,
                                  end - start);
        }

      return result;
    }

It's possible to write some complex number-crunching functions without
relying on the Elisp library. That's the only use-case that I see of
using Emacs like an interpreter and not relying on the "bindings" to the
code that it provides.

--Oleh







reply via email to

[Prev in Thread] Current Thread [Next in Thread]