diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2011-06-27 13:10:53 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2011-06-27 13:10:53 +0300 |
commit | 65b05f3562b1aead4296427c5f6941cb53d94adf (patch) | |
tree | c930a337c8953eed1c318f9c5f77e9af5b1a0b6f | |
parent | 9757309784ffce13a1e70fd1e16790445e237171 (diff) | |
download | cfpeek-65b05f3562b1aead4296427c5f6941cb53d94adf.tar.gz cfpeek-65b05f3562b1aead4296427c5f6941cb53d94adf.tar.bz2 |
Support for detailed input locations.
* gint: Upgrade.
* grecs: Upgrade.
* NEWS: Document changes.
* src/cfpeek.c (_print_diag): Fix prototype.
* src/guile.c (grecs-node-ident-locus)
(grecs-node-value-locus): New functions.
(grecs-node-locus): Take optional second argument. It it is #t,
return full location.
* tests/locus.at: Update.
-rw-r--r-- | NEWS | 31 | ||||
m--------- | gint | 0 | ||||
m--------- | grecs | 0 | ||||
-rw-r--r-- | src/cfpeek.c | 9 | ||||
-rw-r--r-- | src/guile.c | 115 | ||||
-rw-r--r-- | tests/locus.at | 22 |
6 files changed, 154 insertions, 23 deletions
@@ -11,6 +11,37 @@ Version 1.0.90 (Git) * New format flags: down=N, child=S, sibling=S +* New guile primitives: + +- (grecs-node-ident-locus node [full]) + +Returns the location of the node's ident. See below for the meaning +of [full]. + +- (grecs-node-value-locus node [full]) + +Returns the location of the node's value. + +* Full vs. simplified locations. + +There are two flavors of source locations: simplified and full ones. A +simplified location consists of a file name and line number. When returned +from a Guile primitive, they are packed in a cons. A simplified location +shows an approximate location of the object in the configuration file. + +A full location provides an exact location of the object. It consists of +a pair of triplets, which mark the beginning and end of the object. Each +triplet consists of a file name, line number and column number. When +returned from a Guile primitive, each triplet is represented as a list of +three elements and both triplets are packed in a cons, the start location +being its car, and the end location being its cdr. + +The three functions that return node locations, grecs-node-locus, +grecs-node-ident-locus and grecs-node-value-locus, return simplified +locations by default. If the optional second argument is supplied and +is #t, these functions return full locations. + + Version 1.0, 2011-05-27 diff --git a/gint b/gint -Subproject a5774356a1c12d1bcb55b6322710e347e1604fc +Subproject b39efd37a7fbf478072c72f82b4310c8620a4ce diff --git a/grecs b/grecs -Subproject 533420d3ae0697b36218a329f272fbe89430fce +Subproject 5a37057b0ca1b7314f7f338134efc5100dc9223 diff --git a/src/cfpeek.c b/src/cfpeek.c index 3205002..c096dda 100644 --- a/src/cfpeek.c +++ b/src/cfpeek.c @@ -16,6 +16,7 @@ */ #include "cfpeek.h" +#include "grecs-locus.h" int file_index; int flags; @@ -109,13 +110,15 @@ run_locate(struct grecs_node *node) #include "cmdline.h" static void -_print_diag(grecs_locus_t *locus, int err, int errcode, const char *msg) +_print_diag(grecs_locus_t const *locus, int err, int errcode, const char *msg) { fflush(stdout); if (!locus) fprintf(stderr, "%s: ", program_name); - if (locus) - fprintf(stderr, "%s:%d: ", locus->file, locus->line); + if (locus) { + YY_LOCATION_PRINT(stderr, *locus); + fprintf(stderr, ": "); + } if (!err) fprintf(stderr, "warning: "); fprintf(stderr, "%s", msg); diff --git a/src/guile.c b/src/guile.c index 6da81b0..254d671 100644 --- a/src/guile.c +++ b/src/guile.c @@ -177,6 +177,8 @@ _guile_init_node() ((struct _guile_node *) SCM_CDR(obj)); static SCM scm_from_grecs_value(struct grecs_value *val); +static SCM scm_from_grecs_locus_point(struct grecs_locus_point const *pt); +static SCM scm_from_grecs_locus(struct grecs_locus const *locus, int simp); SCM_DEFINE_PUBLIC(scm_grecs_node_p, "grecs-node?", @@ -383,7 +385,39 @@ SCM_DEFINE_PUBLIC(scm_grecs_node_ident, "grecs-node-ident", return scm_from_locale_string(gnp->node->ident ? gnp->node->ident : ""); } #undef FUNC_NAME + +SCM_DEFINE_PUBLIC(scm_grecs_node_ident_locus, "grecs-node-ident-locus", + 1, 1, 0, + (SCM node, SCM full), +"Returns locus of the @var{node}'s identifier. Returned value is a cons\n" +"whose parts depend on @var{full}, which is a boolean value. If @var{full}\n" +"is @samp{#f}, which is the default, then returned value is a cons:\n\n" +"@lisp\n" +"(@var{file-name} . @var{line-number})\n" +"@end lisp\n" +"\n" +"Oherwise, if @var{full} is @samp{#t}, the function returns the locations\n" +"where the node begins and ends:\n" +"@lisp\n" +"((@var{beg-file-name} @var{beg-line} @var{beg-column}) . \n" +" (@var{end-file-name} @var{end-line} @var{end-column}))\n" +"@end lisp\n") +#define FUNC_NAME s_scm_grecs_node_ident_locus +{ + struct _guile_node *gnp; + int full_p = 0; + if (!SCM_UNBNDP(full)) { + SCM_ASSERT(scm_is_bool(full), full, SCM_ARG2, FUNC_NAME); + full_p = full == SCM_BOOL_T; + } + + SCM_ASSERT(CELL_IS_NODE(node), node, SCM_ARG1, FUNC_NAME); + gnp = node_from_scm(node); + return scm_from_grecs_locus(&gnp->node->idloc, full_p); +} +#undef FUNC_NAME + SCM_DEFINE_PUBLIC(scm_grecs_node_path_list, "grecs-node-path-list", 1, 0, 0, (SCM node), @@ -590,23 +624,86 @@ SCM_DEFINE_PUBLIC(scm_grecs_node_value, "grecs-node-value", } #undef FUNC_NAME -SCM_DEFINE_PUBLIC(scm_grecs_node_locus, "grecs-node-locus", - 1, 0, 0, - (SCM node), -"Returns source location of the @var{node}. Returned value is a cons:\n\n" +SCM_DEFINE_PUBLIC(scm_grecs_node_value_locus, "grecs-node-value-locus", + 1, 1, 0, + (SCM node, SCM full), +"Returns locus of the @var{node}'s value. Returned value is a cons\n" +"whose parts depend on @var{full}, which is a boolean value. If @var{full}\n" +"is @samp{#f}, which is the default, then returned value is a cons:\n\n" "@lisp\n" "(@var{file-name} . @var{line-number})\n" +"@end lisp\n" +"\n" +"Oherwise, if @var{full} is @samp{#t}, the function returns the locations\n" +"where the node begins and ends:\n" +"@lisp\n" +"((@var{beg-file-name} @var{beg-line} @var{beg-column}) . \n" +" (@var{end-file-name} @var{end-line} @var{end-column}))\n" +"@end lisp\n") +#define FUNC_NAME s_scm_grecs_node_ident_locus +{ + struct _guile_node *gnp; + int full_p = 0; + + SCM_ASSERT(CELL_IS_NODE(node), node, SCM_ARG1, FUNC_NAME); + gnp = node_from_scm(node); + if (!SCM_UNBNDP(full)) { + SCM_ASSERT(scm_is_bool(full), full, SCM_ARG2, FUNC_NAME); + full_p = full == SCM_BOOL_T; + } + return scm_from_grecs_locus(&gnp->node->v.value->locus, full_p); +} +#undef FUNC_NAME + +static SCM +scm_from_grecs_locus_point(struct grecs_locus_point const *pt) +{ + return scm_list_3(pt->file ? + scm_from_locale_string(pt->file) : SCM_BOOL_F, + scm_from_uint(pt->line), + scm_from_uint(pt->col)); +} + +static SCM +scm_from_grecs_locus(struct grecs_locus const *locus, int full) +{ + return full ? + scm_cons(scm_from_grecs_locus_point(&locus->beg), + scm_from_grecs_locus_point(&locus->end)) : + scm_cons(locus->beg.file ? + scm_from_locale_string(locus->beg.file) : SCM_BOOL_F, + scm_from_uint(locus->beg.line)); +} + +SCM_DEFINE_PUBLIC(scm_grecs_node_locus, + "grecs-node-locus", + 1, 1, 0, + (SCM node, SCM full), +"Returns source location of the @var{node}. Returned value is a cons\n" +"whose parts depend on @var{full}, which is a boolean value. If @var{full}\n" +"is @samp{#f}, which is the default, then returned value is a cons:\n\n" +"@lisp\n" +"(@var{file-name} . @var{line-number})\n" +"@end lisp\n" +"\n" +"Oherwise, if @var{full} is @samp{#t}, the function returns the locations\n" +"where the node begins and ends:\n" +"@lisp\n" +"((@var{beg-file-name} @var{beg-line} @var{beg-column}) . \n" +" (@var{end-file-name} @var{end-line} @var{end-column}))\n" "@end lisp\n") #define FUNC_NAME s_scm_grecs_node_locus { struct _guile_node *gnp; - + int full_p = 0; + SCM_ASSERT(CELL_IS_NODE(node), node, SCM_ARG1, FUNC_NAME); gnp = node_from_scm(node); - return scm_cons(gnp->node->locus.file ? - scm_from_locale_string(gnp->node->locus.file) : - SCM_EOL, - scm_from_int(gnp->node->locus.line)); + if (!SCM_UNBNDP(full)) { + SCM_ASSERT(scm_is_bool(full), full, SCM_ARG2, FUNC_NAME); + full_p = full == SCM_BOOL_T; + } + return scm_from_grecs_locus(&gnp->node->locus, full_p); } #undef FUNC_NAME diff --git a/tests/locus.at b/tests/locus.at index 5fe5918..26074d2 100644 --- a/tests/locus.at +++ b/tests/locus.at @@ -43,17 +43,17 @@ program b { ], [cfpeek -Hdefault,locus], [EX_OK], -[./test.cf:2: .user: smith -./test.cf:3: .group: mail -./test.cf:4: .pidfile: /var/run/example -./test.cf:7: .logging.facility: daemon -./test.cf:8: .logging.tag: example -./test.cf:12: .program="a".command: a.out -./test.cf:14: .program="a".logging.facility: local0 -./test.cf:15: .program="a".logging.tag: a -./test.cf:20: .program="b".command: b.out -./test.cf:21: .program="b".wait: yes -./test.cf:22: .program="b".pidfile: /var/run/b.pid +[./test.cf:2.1-10: .user: smith +./test.cf:3.1-10: .group: mail +./test.cf:4.1-26: .pidfile: /var/run/example +./test.cf:7.5-19: .logging.facility: daemon +./test.cf:8.5-15: .logging.tag: example +./test.cf:12.5-19: .program="a".command: a.out +./test.cf:14.9-23: .program="a".logging.facility: local0 +./test.cf:15.9-13: .program="a".logging.tag: a +./test.cf:20.5-19: .program="b".command: b.out +./test.cf:21.5-12: .program="b".wait: yes +./test.cf:22.5-26: .program="b".pidfile: /var/run/b.pid ]) AT_CLEANUP |