add the possibility to set an 'onchange' property to our members.
authorPierre Habouzit <madcoder@debian.org>
Thu, 29 Mar 2007 22:06:36 +0000 (00:06 +0200)
committerPierre Habouzit <madcoder@debian.org>
Thu, 29 Mar 2007 22:06:36 +0000 (00:06 +0200)
use that for MCharset.charset.

Signed-off-by: Pierre Habouzit <madcoder@debian.org>
charset.cpkg
tools/cpkg2c.mll

index 6934987..f491e05 100644 (file)
@@ -62,10 +62,13 @@ static char *charset_init(void)
 #ifdef HAVE_BIND_TEXTDOMAIN_CODESET
     bind_textdomain_codeset(PACKAGE, res);
 #endif
+    return m_strdup(res);
+}
 
-    Charset_is_utf8    = charset_is_utf8(res);
+static void charset_onchange(const char *cset)
+{
+    Charset_is_utf8    = charset_is_utf8(cset);
     CharsetReplacement = Charset_is_utf8 ? 0xfffd : '?';
-    return m_strdup(res);
 }
 
 @package MCharset {
@@ -91,7 +94,10 @@ static char *charset_init(void)
      ** .pp
      ** Character set your terminal uses to display and enter textual data.
      */
-    string_t charset         = charset_init();
+    string_t charset = {
+        .init     = charset_init();
+        .onchange = charset_onchange($$);
+    };
 
     /*
      ** .pp
index 57e8258..b5ef25a 100644 (file)
@@ -51,9 +51,9 @@
     }
   let typedef0 =
     { lpos  = 0; fpos = "";
-      ctype = ("", "", 0);
-      check = ("", "", 0);
-      push  = ("", "", 0);
+      ctype = "", "", 0;
+      check = "", "", 0;
+      push  = "", "", 0;
       ctor  = None;
       dtor = None
     }
   type typinst = bool * typedef
 
   type members =
-    { typ: typinst; mname: string; init: string }
+    { typ: typinst; mname: string;
+      init: string anchor; onchange: string anchor option; }
+  let member0 =
+    { typ   = false, typedef0;
+      mname = "";
+      init = "", "", 0;
+      onchange = None;
+    }
 
   type methods =
     { rettype: typinst list; args: (typinst * string) list;
@@ -278,13 +285,23 @@ and ext_pkg pkg = parse
 | '\n'              { ext_pkg pkg (nextl lexbuf) }
 | "/*"              { let _ = cComment (B.create 1024) lexbuf in
                       ext_pkg pkg lexbuf }
+| ("const" sp+ as const)? (ident as typ) sp+
+  (ident as member) sp* '=' sp* '{'
+                    {
+                      let m = {member0 with mname = member;
+                               typ = const != None, type_find (lnum lexbuf)
+                               pkg.file typ; } in
+                      let m = ext_member m pkg.file lexbuf in
+                      ext_pkg {pkg with members = (m, pkg.file, lnum lexbuf)::pkg.members} lexbuf
+                    }
 | ("const" sp+ as const)? (ident as typ) sp+
   (ident as member) sp* '=' sp* ([^';''\n']* as init)';'
                     {
                       let m = { typ   = const != None,
                                         type_find (lnum lexbuf) pkg.file typ;
                                 mname = member;
-                                init  = init; }, pkg.file, lnum lexbuf in
+                                init  = init, pkg.file, lnum lexbuf;
+                                onchange = None; }, pkg.file, lnum lexbuf in
                       ext_pkg {pkg with members = m::pkg.members} lexbuf
                     }
 | '(' ((typdecl ',')* typdecl as ret) ')' sp*
@@ -333,6 +350,30 @@ and ext_bodycode buf = parse
 | '}'     as c      { buf @< c }
 | _       as c      { ext_bodycode (buf @< c) lexbuf }
 
+(* }}} *)
+(* parse extended member {{{ *)
+
+and ext_member m f = parse
+| sp+
+| "//" to_eol       { ext_member m f lexbuf }
+| '\n'              { ext_member m f (nextl lexbuf) }
+| "/*"              { let _ = cComment (B.create 1024) lexbuf in
+                      ext_member m f lexbuf }
+| '.' (ident as member) sp* '=' sp* ([^';''\n']+ as s) ';'
+                    {
+                      ext_member (
+                        let do_anch s = s, f, lnum lexbuf in
+                        match member with
+                        | "init"     -> {m with init = do_anch s}
+                        | "onchange" -> {m with onchange = Some(do_anch s)}
+                        | _       ->
+                            die (lnum lexbuf) f
+                              (sprintf "Unknown directive `%s'" member)
+                      ) f lexbuf
+                    }
+| '}' sp* ';'       { m }
+| ""                { die (lnum lexbuf) f "Syntax error" }
+
 (* }}} *)
 
 {
@@ -444,18 +485,26 @@ and ext_bodycode buf = parse
           else
             printf "struct luaM_%s_t %s = {\n" pkg.name pkg.name
           );
-          List.iter (function (m, f, l) ->
+          List.iter (function (m, _, _) ->
+              let (init, f, l) = m.init in
               put_line l f;
-              printf "    %s,\n" (if fst m.typ then m.init else "0")
+              printf "    %s,\n" (if fst m.typ then init else "0")
             ) pkg.members;
           printf "};\n";
 
           (* dump struct init func *)
           printf "\nstatic void %s_init(void)\n{\n" pkg.name;
-          List.iter (function (m, f, l) ->
+          List.iter (function (m, _, _) ->
             if not (fst m.typ) then
-              printf "#line %d \"%s\"\n    %s.%s = %s;\n"
-              l f pkg.name m.mname m.init) pkg.members;
+              let init, f, l = m.init in
+              let field = sprintf "%s.%s" pkg.name m.mname in
+              put_line l f;
+              printf "    %s = %s;\n" field init;
+              match m.onchange with
+              | None           -> ()
+              | Some(on, f, l) ->
+                  put_line l f; printf "    %s;\n" (tplize on field)
+            ) pkg.members;
           printf "};\n\n";
 
           (* dump __index *)
@@ -479,6 +528,7 @@ and ext_bodycode buf = parse
           printf "    const char *idx = luaL_checkstring(L, 2);\n\n";
           printf "    switch (mlua_which_token(idx, -1)) {\n";
           List.iter (function (m, _, _) ->
+            let field = sprintf "%s.%s" pkg.name m.mname in
             match m.typ with
             | true, _ -> ()
             | false, t ->
@@ -487,20 +537,26 @@ and ext_bodycode buf = parse
               | None -> ()
               | Some (dtor, f, l) ->
                   put_line l f;
-                  printf "        %s;\n" (tplize dtor (sprintf "&%s.%s" pkg.name m.mname))
+                  printf "        %s;\n" (tplize dtor ("&" ^ field))
               );
               (match t.ctor with
               | None ->
                   let (c, f, l) = t.check in
                   put_line l f;
-                  printf "        %s.%s = %s;\n" pkg.name m.mname (tplize c "3")
+                  printf "        %s = %s;\n" field (tplize c "3")
               | Some (ctor, f, l) ->
                   let v =
                     let c, f, l = t.check in
                     tplize (sprintf "\n#line %d \"%s\"\n            %s" l f c) "3"
                   in
                   put_line l f;
-                  printf "        %s.%s = %s;\n" pkg.name m.mname (tplize ctor v)
+                  printf "        %s = %s;\n" field (tplize ctor v)
+              );
+              (match m.onchange with
+              | None           -> ()
+              | Some(on, f, l) ->
+                  put_line l f;
+                  printf "        %s;\n" (tplize on field)
               );
               printf "        return 1;\n"
           ) pkg.members;