www.delorie.com/archives/browse.cgi   search  
Mail Archives: geda-user/2013/03/17/17:02:33

X-Authentication-Warning: delorie.com: mail set sender to geda-user-bounces using -f
X-Recipient: geda-user AT delorie DOT com
Message-ID: <51462F03.7010502@buffalo.edu>
Date: Sun, 17 Mar 2013 17:00:51 -0400
From: "Stephen R. Besch" <sbesch AT buffalo DOT edu>
User-Agent: Mozilla/5.0 (X11; Linux i686; rv:17.0) Gecko/20130307 Thunderbird/17.0.4
MIME-Version: 1.0
To: geda-user AT delorie DOT com
Subject: [geda-user] Access to geda mailing lists.
X-PM-EL-Spam-Prob: : 9%
Reply-To: geda-user AT delorie DOT com

This is a multi-part message in MIME format.
--------------030008060109060409010203
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit

Has anyone noticed that the documentation attribute in gschem no longer 
works very well? That is, it always goes to the WEB for datasheets and 
the gschemdoc documentation is very misleading about how to make this 
work with local files. It used to use "locate" to find files, but now 
uses a scheme strategy, no doubt to facilitate the Window's port, but 
which is horribly broken on linux. This has been bugging me for a while 
now, so I dug into the code and fixed it. I have attached a text file of 
what I had to add/change to make gschemdoc look in the component's 
directory for a documentation folder. This way each symbol library 
folder has it's own documents that move with them. If there is no 
document file found there, it fall back on the current method.

Stephen R. Besch, Ph.D.

-- 
fictio cedit veritati


--------------030008060109060409010203
Content-Type: text/plain; charset=UTF-8;
 name="Changes.txt"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
 filename="Changes.txt"

Documentation bug.

Sometime between gschem V1.6.1.20100214 and the current (git repository) version  1.9.0(g1814f28), the component documentation function has been broken. Where formerly a documentation file could be put into a folder of the user's choice and a bash script which used locate to find and display the file. The newest version now uses a scheme script (gschemdoc.scm) for the same purpose. The only problem is that it does not seem to work at all anymore - referring all documentation requests to the web.

This is bad for two reasons. First, the web fetching of documents is very musch slower and of course makes it much more difficult when working off-line. Second, the internet search often fails - stale links are found, web-sites referring links don't work, the PDF's won't display, or worst of all, some enterprising soul has decided to charge you a fee to see datasheets that can almost always be found for free. It is really much better to download a datasheet once it is located and not have to find it again (and again - and again...).

Now, according to the documentation for gschemdoc, if I place the documents in the "current working directory" or in the "gEDA documentation" directory, this function will still work. And yes, it does except for two major problems. First, it is implied that there is a directory in "usr/local/share/gEDA" named "documentation", when if fact there is not. Adding this directory and putting documentation files into it does not work. Second, putting the files into the "Current working directory" works but is unacceptable because it means that a copy has to be put into each and every project directory. Not to mention that it is not at all obvious what the current working directory might be:  The startup directory of gschem - or the location of the project file? It turns out to be the latter.

In all fairness, I was able to discover the directories that gschemdoc explores, but only by sticking a (write filename) function into gschemdoc.scm and copying down the results. That's how I confirmed the current working directory and also discovered that the "documentation" directory was actually called "doc" and was located in "/usr/local/share/doc/geda-gaf/" Apparently putting files in here would solve the problem. I reiterate, this is a really, really bad idea.

Rather than work around this problem, I dug into the sources to see if I might be able to fix this directly -and this turned out to be easier that I had initially thought. In fact, a colleage and I spent about an hour getting this to work. Compared to the many hours I spent thrashing about trying to get my documentation files to show, the fix was a breeze.

The fix is this: First, look in the directory where the symbol is loaded for a "documentation" folder and if found, look there to see if the file specified in the "documention" attribute is located in that directory. If not, fall back to the default behavior and look on the WEB. This allows me to get missing files from the web and install them in the symbol's documention folder. While this scheme isn't ideal for predefined gEDA/gaf symbols (it works, but requires changing the installation folders, which is always a bad idea since you are likely to lose a lot of documentation every time gEDA/gaf is updated or recompiled. Any symbols in the user's private symbol libraries are however ideally treated in this manner.

Here's what needs to be done. First, while the component library code knows the folder that a symbol lives in, it does not expose this information to gschemdoc. This means that we need to alter the component library code to add the directory information. Thus a function declaration is added to is added to libgeda/include/prototype.h after line 292. In my sources the code at line 292 is:

    gchar *s_clib_symbol_get_filename (const CLibSymbol *symbol);

Then add this on the next line:

	gchar *s_clib_symbol_get_directory (const CLibSymbol *symbol);

Save the file and then open libgeda/src/s_clib.c to add the function definition. I added the code just following the gchar *s_clib_symbol_get_filename (const CLibSymbol *symbol) definition. The code, including the function description appears at line 1045 in my sources:

/*! \brief Get a directory for getting symbol documentation.  
 *  \par Function Description
 *  Get the filename of the directory a symbol was loaded from, if possible
 *  (to allow keeping documentation in symbol's folder).
 *
 *  \todo This is hack until mainstream fixes broken documentation code (or accepts
 *  my patch) SRB.
 *
 *  \param symbol Symbol to be examined.
 *  \return pointer to string containing path to symbol's Directory.
 */
 
gchar *s_clib_symbol_get_directory (const CLibSymbol *symbol){
  if (symbol == NULL) return NULL;
  if (symbol->source->type != CLIB_DIR) return NULL;
  return symbol->source->directory;
}

We now have a callable function that will return a pointer to a gchar string. The next task is to get this string back up to a level where gschemdoc can get at it. This means a small change to the complex_info function, located at line 191 in libgeda/src/scheme_complex.c:

SCM_DEFINE (complex_info, "%complex-info", 1, 0, 0,
            (SCM complex_s), "Get complex object parameters.")
{
  SCM_ASSERT (edascm_is_object_type (complex_s, OBJ_COMPLEX), complex_s,
              SCM_ARG1, s_complex_info);

  OBJECT *obj = edascm_to_object (complex_s);
  const CLibSymbol *clib = s_clib_get_symbol_by_name (obj->complex_basename); //Added by SRB
  
  return scm_list_n (scm_from_utf8_string (obj->complex_basename),
                     scm_from_int (obj->complex->x),
                     scm_from_int (obj->complex->y),
                     scm_from_int (obj->complex->angle),
                     obj->complex->mirror ? SCM_BOOL_T : SCM_BOOL_F,
                     obj->selectable ? SCM_BOOL_F : SCM_BOOL_T,
                     scm_from_utf8_string (s_clib_symbol_get_directory(clib)), //Added by SRB
                     SCM_UNDEFINED);
}

The comments show the added lines. The first added line defines the object pointer we will need to call the function we added to fetch the directory. The second line adds the directory to end of the list returned by the function (well, almost the end - SCM_UNDEFINED must remain the last entry). We can get away with expanding this list because of the way the list is used by higher level code. Since no-one ever indexes the item we added, it has no effect on other functions. Then, since gschemdoc compresses the list by putting X and Y into a sub-list and then uses the tail function to copy down the entire end of the list, our newly added item is sitting there waiting to be used. 

However, gschemdoc can't get it directly so we need to define another simple function in libgeda/scheme/object.scm. This function simply puts a wrapper around a call to component_info to fetch the 5th item in the list (which just happens to be our new entry). I stuck this in at line 394, just after the definition of (component-locked? c):
  
(define-public (component-dirname c)    ;;Added by SRB
  (list-ref (component-info c) 5))

At this point, gschemdoc.scm has access to the directory information. The last bit then is changing gschemdoc to use the directory in the search for the doc files. Now open gschem/scheme/gschemdoc.scm and find the line containing "(define-public (show-component-documentation obj)". This is the routine that needs changing. The fragment shown below has several changes from the dist. code. First, the description was altered to indicate the addition of the component documention path to the search list. Second, a line was added to fetch the component's directory and store it in "docdir". Then, a line was added inside the "OR" block (labeled a2) which actually does the search. If successful, document is displayed. If unsuccessful, routine falls back on default search. Here is the fragment:


(define-public (show-component-documentation obj)
  "show-component-documentation COMPONENT

Find the documentation for COMPONENT, by inspecting (in order) its
\"documentation\", \"device\" and \"value\" attributes, and its
component basename, and searching in the current directory, the component
documentation directory (SRB) the system gEDA documentation directory,
and Google.  In most cases, results are restricted to \".pdf\" files.
The documentation is displayed in the system associated viewer application."


  (let ((documentation (attribute-value-by-name obj "documentation"))
        (device (attribute-value-by-name obj "device"))
        (value (attribute-value-by-name obj "value"))
        (basename (component-basename obj))
        (docdir (string-append (component-dirname obj) separator "documentation")))

    ;; Try several different ways of finding documentation
    (or

     ;; 1) Checks based on "documentation=" attribute
     (and
      documentation

      (or
       ;; a) First check the obvious -- does the documentation
       ;;    attribute match a file in the current directory?
       (directory-doc-search (getcwd) documentation)
       ;; a2) Then check for file in the components directory
       (directory-doc-search docdir documentation)
       ;; b) What about in the documentation directory?
       (directory-doc-search (sys-doc-dir) documentation)

The rest of the routine was not changed. Once all changes are in place, you need to make then make install. It is not necessary to re-run configure. Once you've got things working, you should probably commit the changes to your local git repository so that you can merge any changes in future updates and not have to do this all over again.

Final comments. I have tested this out rather well and found no bugs, but there may be issues I am not aware of. Nevertheless, to use the patch you will need to have a "documentation" directory in each local-symbol directory and then copy the respective document files into this directory. Once this is done, the documents will travel with the symbols into every project that uses them.
 


--------------030008060109060409010203--

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019