unofficial mirror of guile-user@gnu.org 
 help / color / mirror / Atom feed
* Clean Guile code from C program
@ 2008-03-07 18:02 Jose Martin
  2008-03-07 18:30 ` Mike Gran
  2008-03-07 20:04 ` Neil Jerram
  0 siblings, 2 replies; 5+ messages in thread
From: Jose Martin @ 2008-03-07 18:02 UTC (permalink / raw)
  To: guile-user


Hi all, I need to use a program in C that is designed to be used in Guile. I'm not a Guile user myself so I don't know well how to remove the Guile code from the C program, so that I can run it without Guile (Please, don't be ofended for that ;) ).



I looked at the program's code and it looks a bit difficult to change it, and I must say I'm a beginner in C. Could anyone give me the steps of the changes I'd need to remove Guile-dependent code from C code?



The program has about 10 files, so here I'm pasting only one of the files. The code is open-source so I could share it if anyone wants to see the other files.



I'd massively appreciate any help. Thanks,



Jose



-- ATTACHED CODE --



#include <guile/gh.h>

...



#define INFO contain

#define TEXTMGRP(x) (SCM_NIMP(x) && SCM_CAR(x) == (SCM)scm_tc16_textmgr)

#define TEXTMGR(x) ((TextFile*) SCM_CDR(x))



long scm_tc16_textmgr;



SCM mark_textmgr(SCM obj)

{

  SCM_SETGC8MARK(obj);

  return SCM_BOOL_F;

}



size_t free_textmgr(SCM obj)

{

  if (TEXTMGR(obj)) {

    TEXTMGR(obj)->foreach(markref);

    TEXTMGR(obj)->hashtable()->foreach(decref);

    delete TEXTMGR(obj);

  }

  return 0;

}



int print_textmgr(SCM obj, SCM port, scm_print_state * pstate)

{

  scm_puts("#<TEXT: ", port);

  scm_puts(TEXTMGR(obj)->filename(), port);

  scm_puts(">", port);

  return 1;

}



SCM textmgr2scm(TextFile* text)

{

  SCM result;

  SCM_NEWCELL(result);

  SCM_SETCAR(result, (SCM) scm_tc16_textmgr);

  SCM_SETCDR(result, (SCM) text);

  return result;

}





SCM_PROC(s_open_text, "open-text", 1, 0, 0, open_text);

SCM open_text(SCM name)

{

  SCM txt;

  if (scm_string_p(name) != SCM_BOOL_T)

    scm_wrong_type_arg(s_open_text, 1, name);

  txt = textmgr2scm(new TextFile(SCM_CHARS(name)));

  TEXTMGR(txt)->foreach(markref);

  TEXTMGR(txt)->hashtable()->foreach(incref);

  return txt;

}



SCM_PROC(s_append_text, "append-text", 2, 0, 0, append_text);

SCM append_text(SCM obj, SCM name)

{

  if (!TEXTMGRP(obj))

    scm_wrong_type_arg(s_append_text, 1, obj);

  if (!TEXTMGR(obj))

    scm_misc_error(s_append_text, "Text object is empty", SCM_EOL);

  if (scm_string_p(name) != SCM_BOOL_T)

    scm_wrong_type_arg(s_append_text, 2, name);

  TEXTMGR(obj)->foreach(markref);

  TEXTMGR(obj)->hashtable()->foreach(decref);

  TEXTMGR(obj)->append(SCM_CHARS(name));

  TEXTMGR(obj)->foreach(markref);

  TEXTMGR(obj)->hashtable()->foreach(incref);

  return obj;

}



SCM_PROC(s_close_text, "close-text", 1, 0, 0, close_text);

SCM close_text(SCM obj)

{

  if (!TEXTMGRP(obj))

    scm_wrong_type_arg(s_close_text, 1, obj);

  if (TEXTMGR(obj)) {

    scm_gc();

    TEXTMGR(obj)->foreach(markref);

    TEXTMGR(obj)->hashtable()->foreach(decref);

    TEXTMGR(obj)->hashtable()->removeif(delrefp);

    delete TEXTMGR(obj);

    SCM_SETCDR(obj, 0);

  }

  return SCM_UNSPECIFIED;

}



SCM_PROC(s_rewind_text, "rewind-text", 1, 0, 0, rewind_text);

SCM rewind_text(SCM obj)

{

  if (!TEXTMGRP(obj))

    scm_wrong_type_arg(s_rewind_text, 1, obj);

  if (!TEXTMGR(obj))

    scm_misc_error(s_rewind_text, "Text object is empty", SCM_EOL);

  TEXTMGR(obj)->rewind();

  return SCM_UNSPECIFIED;

}



SCM_PROC(s_get_next_word, "get-next-word", 1, 0, 0, get_next_word);

SCM get_next_word(SCM obj)

{

  contain* cn;

  if (!TEXTMGRP(obj))

    scm_wrong_type_arg(s_get_next_word, 1, obj);

  if (!TEXTMGR(obj))

    scm_misc_error(s_get_next_word, "Text object is empty", SCM_EOL);

  cn = TEXTMGR(obj)->getnext();

  if (cn)

    return cn->content;

  else

    return SCM_BOOL_F;

}



SCM_PROC(s_get_word, "get-word", 2, 0, 0, get_word);

SCM get_word(SCM obj, SCM n)

{

  contain* cn;

  if (!TEXTMGRP(obj))

    scm_wrong_type_arg(s_get_word, 1, obj);

  if (!TEXTMGR(obj))

    scm_misc_error(s_get_word, "Text object is empty", SCM_EOL);

  if (scm_integer_p(n) != SCM_BOOL_T)

    scm_wrong_type_arg(s_get_word, 2, n);

  cn = TEXTMGR(obj)->get(gh_scm2int(n));

  if (cn)

    return cn->content;

  else

    return SCM_BOOL_F;

}



SCM_PROC(s_scramble_text, "scramble-text", 1, 0, 0, scramble_text);

SCM scramble_text(SCM obj)

{

  if (!TEXTMGRP(obj))

    scm_wrong_type_arg(s_scramble_text, 1, obj);

  if (!TEXTMGR(obj))

    scm_misc_error(s_scramble_text, "Text object is empty", SCM_EOL);

  return textmgr2scm(TEXTMGR(obj)->scramble());

}



static SCM currentproc = 0;



void iterproc(contain* cn)

{

  gh_call1(currentproc, cn->content);

}



SCM_PROC(s_for_each_word, "for-each-word", 2, 0, 0, for_each_word);

SCM for_each_word(SCM obj, SCM proc)

{

  SCM lastproc = currentproc;

  if (!TEXTMGRP(obj))

    scm_wrong_type_arg(s_for_each_word, 1, obj);

  if (!TEXTMGR(obj))

    scm_misc_error(s_for_each_word, "Text object is empty", SCM_EOL);

  currentproc = proc;

  TEXTMGR(obj)->foreach(iterproc);

  currentproc = lastproc;

  return SCM_UNSPECIFIED;

}



SCM_PROC(s_for_each_unique_word, "for-each-unique-word", 1, 0, 0, for_each_unique_word);

SCM for_each_unique_word(SCM proc)

{

  SCM lastproc = currentproc;

  currentproc = proc;

  TextFile::table.foreach(iterproc);

  currentproc = lastproc;

  return SCM_UNSPECIFIED;

}



SCM_PROC(s_lookup_word, "lookup-word", 1, 0, 0, lookup_word);

SCM lookup_word(SCM obj)

{

  contain* cn;

  if (scm_string_p(obj) != SCM_BOOL_T)

    scm_wrong_type_arg(s_lookup_word, 1, obj);

  cn = TextFile::table.get(SCM_CHARS(obj));

  if (cn)

    return cn->content;

  else

    return SCM_BOOL_F;

}



SCM_PROC(s_create_word, "create-word", 0, 0, 1, create_word);

SCM create_word(SCM args)

{

  SCM obj;

  contain* cn;

  if (scm_ilength(args) < 1)

    scm_wrong_num_args(scm_makfrom0str(s_create_word));

  obj = SCM_CAR(args);

  if (scm_string_p(obj) != SCM_BOOL_T)

    scm_wrong_type_arg(s_create_word, 1, obj);

  cn = TextFile::table.insert(SCM_CHARS(obj));

  cn->refcount += 2;

  SCM_SETCDR(cn->content, SCM_CDR(args));

  return cn->content;

}



SCM_PROC(s_check_text_sections, "check-text-sections", 1, 0, 0, check_text_sections);

SCM check_text_sections(SCM tag)

{

  if (tag == SCM_BOOL_F) {

    TextFile::CheckNewline = 0;

  } else if (tag == SCM_BOOL_F) {

    TextFile::CheckNewline = 1;

  } else if (scm_string_p(tag) == SCM_BOOL_T) {

    TextFile::CheckNewline = 1;

    TextFile::CheckNewlineResult = strcpy(new char[strlen(SCM_CHARS(tag))], SCM_CHARS(tag));

  } else

    scm_wrong_type_arg(s_check_text_sections, 1, tag);

  return SCM_UNSPECIFIED;

}



static SCM globalport;



void csave(contain* cn)

{

  scm_write(cn->content, globalport);

  scm_newline(globalport);

}



SCM cread()

{

  SCM res;

  res = scm_read(globalport);

  if (res == SCM_EOF_VAL || !SCM_CONSP(res) ||

      scm_string_p(SCM_CAR(res)) != SCM_BOOL_T)

    return SCM_BOOL_F;

  else

    return res;

}



SCM_PROC(s_export_words, "export-words", 1, 0, 0, export_words);

SCM export_words(SCM obj)

{

  if (scm_string_p(obj) != SCM_BOOL_T)

    scm_wrong_type_arg(s_export_words, 1, obj);

  globalport = scm_open_file(obj, scm_makfrom0str("w"));

  scm_protect_object(globalport);

  TextFile::table.foreach(csave);

  scm_close_port(globalport);

  scm_unprotect_object(globalport);

  return SCM_UNSPECIFIED;

}



SCM_PROC(s_import_words, "import-words", 1, 0, 0, import_words);

SCM import_words(SCM obj)

{

  SCM ele;

  if (scm_string_p(obj) != SCM_BOOL_T)

    scm_wrong_type_arg(s_import_words, 1, obj);

  globalport = scm_open_file(obj, scm_makfrom0str("r"));

  scm_protect_object(globalport);

  while ((ele = cread()) != SCM_BOOL_F)

    SCM_SETCDR(TextFile::table.insert(SCM_CHARS(SCM_CAR(ele)))->content,

               SCM_CDR(ele));

  scm_close_port(globalport);

  scm_unprotect_object(globalport);

  return SCM_UNSPECIFIED;

}



void init_gltext()

{

  scm_tc16_textmgr = scm_make_smob_type("textmgr", 0);

  scm_set_smob_mark(scm_tc16_textmgr, mark_textmgr);

  scm_set_smob_free(scm_tc16_textmgr, free_textmgr);

  scm_set_smob_print(scm_tc16_textmgr, print_textmgr);

#include "gltext.x"

}



-------------------------------------------------------------------------------------

#include <guile/gh.h>

...



void main2(int argc, char** argv)

{

...



  scm_eval_0str("(define-module (guile) :use-module (ice-9 readline))"); 

  scm_eval_0str("(define-module (guile-user) :use-module (ice-9 readline))"); 

  scm_eval_0str("(activate-readline)"); 

  scm_eval_0str("(set-repl-prompt! \"gsdm> \")");

  scm_shell (argc, argv);

}



int main(int argc, char** argv)

{

  gh_enter(argc, argv, main2);

  return 0;

}

_______________________________________________
Join Excite! - http://www.excite.com
The most personalized portal on the Web!






^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Clean Guile code from C program
  2008-03-07 18:02 Jose Martin
@ 2008-03-07 18:30 ` Mike Gran
  2008-03-07 19:01   ` Luigi Semenzato
  2008-03-07 20:04 ` Neil Jerram
  1 sibling, 1 reply; 5+ messages in thread
From: Mike Gran @ 2008-03-07 18:30 UTC (permalink / raw)
  To: maitai02, guile-user

--- Jose Martin <maitai02@excite.com> wrote:

> I looked at the program's code and it looks a bit
> difficult to change it, and I must say I'm a
> beginner in C. Could anyone give me the steps of the
> changes I'd need to remove Guile-dependent code from
> C code?

Wow.  The Guile stuff is pretty well entangled.  If
you don't know enough C (and I think I saw some C++ in
there as well) you might be in over your head.

But, FWIW, here's how you'd do it.

1.  For every variable and function declared as type
SCM, figure out what type of information actually goes
in that variable.  Choose an appropriate C type
instead.

1a.  This code creates a special Guile type textmgr
which is, underneath, a C++ class textmgr.  Wherever
the textmgr stuff is used, call the C++ class's
procecures instead.

2.  For every function that begins with scm_, check
the docs for its purpose and recode them in C.  You
can usually ignore the scm_????_p functions because
they check the type of the variable, which won't be
necessary once you convert everything into appropriate
C types.

3.  The scm_shell creates a loop that displays a
prompt, takes user-typed commands, executes them, and
displays the output.  Invent some sort of input scheme
or input language and write a parser for it.  Have it
execute the commands that the user typed in.  (The
"readline" calls invoke a library called readline
which does command history stuff.  Your parser could
use the C API of readline instead.)

4.  Make sure that your C datatypes are freed
appropriately.

5. ???

6. Profit!

Good luck!

--
Mike Gran






^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Clean Guile code from C program
  2008-03-07 18:30 ` Mike Gran
@ 2008-03-07 19:01   ` Luigi Semenzato
  0 siblings, 0 replies; 5+ messages in thread
From: Luigi Semenzato @ 2008-03-07 19:01 UTC (permalink / raw)
  To: Mike Gran; +Cc: guile-user

It's not clear that Mike's asking the right question here.
If he wants to get rid of Guile from his program, first he
needs to check if the program contains any Guile code
which uses this code.  It's possible that a substantial
amount of the program's functionality has been
written in Guile.  In that case converting these
functions, which are Guile-specific, to C won't help much.

A better approach is to understand what the Guile
part of the program is doing and figuring out how
to convert that part to C.  Most likely, the best way
of doing that will not use any of the C-Guile interface.

It's possible (but quite unlikely) that all calls into this code
come from other C code.  Then the advice applies, although
even in this case it may be easier to rewrite the C code
from scratch.

Also, the code is a little suspicious.  Take a look at this
fragment below:

SCM check_text_sections(SCM tag)

{

 if (tag == SCM_BOOL_F) {

   TextFile::CheckNewline = 0;

 } else if (tag == SCM_BOOL_F) {

   TextFile::CheckNewline = 1;

...


Before asking Guile-specific questions, Mike should backtrack
and get advice on how to solve his problem (probably on a different
forum).  He may very well be going down the wrong path.

Luigi


On 3/7/08, Mike Gran <spk121@yahoo.com> wrote:
> --- Jose Martin <maitai02@excite.com> wrote:
>
>  > I looked at the program's code and it looks a bit
>  > difficult to change it, and I must say I'm a
>  > beginner in C. Could anyone give me the steps of the
>  > changes I'd need to remove Guile-dependent code from
>  > C code?
>
>
> Wow.  The Guile stuff is pretty well entangled.  If
>  you don't know enough C (and I think I saw some C++ in
>  there as well) you might be in over your head.
>
>  But, FWIW, here's how you'd do it.




^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Clean Guile code from C program
  2008-03-07 18:02 Jose Martin
  2008-03-07 18:30 ` Mike Gran
@ 2008-03-07 20:04 ` Neil Jerram
  1 sibling, 0 replies; 5+ messages in thread
From: Neil Jerram @ 2008-03-07 20:04 UTC (permalink / raw)
  To: maitai02; +Cc: guile-user

"Jose Martin" <maitai02@excite.com> writes:

> Hi all, I need to use a program in C that is designed to be used in
> Guile. I'm not a Guile user myself so I don't know well how to remove
> the Guile code from the C program, so that I can run it without Guile
> (Please, don't be ofended for that ;) ).

Hi Jose,

Others are already giving useful advice, so I won't duplicate that.
I'd be interested to hear a bit more, though, about what the program
is, how it came to use Guile until now, and why you are interested now
in taking Guile out.

(I'm not offended; but curious, and wondering if there are any other
options that we could help you with.)

Best wishes,
     Neil





^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Clean Guile code from C program
@ 2008-03-08 20:10 Jose Martin
  0 siblings, 0 replies; 5+ messages in thread
From: Jose Martin @ 2008-03-08 20:10 UTC (permalink / raw)
  To: guile-user




> I'd be interested to hear a bit more, though, about what the program

> is, how it came to use Guile until now, and why you are interested 

> now in taking Guile out.



Thanks guys for the helpful advice.



Neil, the program is developed for experiments in research in linguistics. It's unknown to me how it came to use Guile. The program has to be used from a Guile prompt, using predefined Guile scripts. 



I don't have any negative opinion about Guile for not using it. I need to integrate the program as library in a larger program, and I'd prefer to directly access the functions in the C code. A second reason to remove Guile is that other people will continue to work on this code, and it's a bit difficult  to understand what it does having mixed Guile into the C/C++ code.



I'd prefer the approach that creates a separate wrapper file with the interface functions to access C/C++, which I think it's what SWIG does to create the interface with Guile. 



Thanks,

Jose

_______________________________________________
Join Excite! - http://www.excite.com
The most personalized portal on the Web!






^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2008-03-08 20:10 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-03-08 20:10 Clean Guile code from C program Jose Martin
  -- strict thread matches above, loose matches on Subject: below --
2008-03-07 18:02 Jose Martin
2008-03-07 18:30 ` Mike Gran
2008-03-07 19:01   ` Luigi Semenzato
2008-03-07 20:04 ` Neil Jerram

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).