| | 1 | /* |
| | 2 | * Copyright (c) 2002 by Michael J. Roberts. All Rights Reserved. |
| | 3 | * |
| | 4 | * Please see the accompanying license file, LICENSE.TXT, for information |
| | 5 | * on using and copying this software. |
| | 6 | */ |
| | 7 | /* |
| | 8 | Name |
| | 9 | vmpat.h - regular-expression compiled pattern object |
| | 10 | Function |
| | 11 | Encapsulates a compiled regular expression as an object. This object |
| | 12 | allows a compiled regular expression to be saved for re-use; since regex |
| | 13 | compilation is time-consuming, it's much more efficient to re-use a |
| | 14 | compiled pattern in repeated searches than to recompile the expression |
| | 15 | each time it's needed. |
| | 16 | Notes |
| | 17 | |
| | 18 | Modified |
| | 19 | 08/27/02 MJRoberts - Creation |
| | 20 | */ |
| | 21 | |
| | 22 | #ifndef VMPAT_H |
| | 23 | #define VMPAT_H |
| | 24 | |
| | 25 | #include <stdlib.h> |
| | 26 | #include <os.h> |
| | 27 | #include "vmtype.h" |
| | 28 | #include "vmobj.h" |
| | 29 | #include "vmglob.h" |
| | 30 | #include "vmregex.h" |
| | 31 | |
| | 32 | /* ------------------------------------------------------------------------ */ |
| | 33 | /* |
| | 34 | * Our serialized data stream, in both the image file and a saved file, |
| | 35 | * consists of: |
| | 36 | * |
| | 37 | * DATAHOLDER src_val |
| | 38 | * |
| | 39 | * 'src_val' is the source value - this is the string that was compiled to |
| | 40 | * create the pattern. |
| | 41 | */ |
| | 42 | |
| | 43 | /* ------------------------------------------------------------------------ */ |
| | 44 | /* |
| | 45 | * Our in-memory extension consists of a simple structure with a pointer |
| | 46 | * to the compiled pattern data (the re_compiled_pattern structure) and |
| | 47 | * the original string value that was used to create the pattern (we hold |
| | 48 | * onto the original string mostly for debugging purposes). |
| | 49 | */ |
| | 50 | struct vmobj_pat_ext |
| | 51 | { |
| | 52 | /* the compiled pattern data */ |
| | 53 | re_compiled_pattern *pat; |
| | 54 | |
| | 55 | /* the original pattern source string */ |
| | 56 | vm_val_t str; |
| | 57 | }; |
| | 58 | |
| | 59 | /* ------------------------------------------------------------------------ */ |
| | 60 | /* |
| | 61 | * Pattern intrinsic class |
| | 62 | */ |
| | 63 | class CVmObjPattern: public CVmObject |
| | 64 | { |
| | 65 | friend class CVmMetaclassPattern; |
| | 66 | |
| | 67 | public: |
| | 68 | /* metaclass registration object */ |
| | 69 | static class CVmMetaclass *metaclass_reg_; |
| | 70 | class CVmMetaclass *get_metaclass_reg() const { return metaclass_reg_; } |
| | 71 | |
| | 72 | /* am I of the given metaclass? */ |
| | 73 | virtual int is_of_metaclass(class CVmMetaclass *meta) const |
| | 74 | { |
| | 75 | /* try my own metaclass and my base class */ |
| | 76 | return (meta == metaclass_reg_ |
| | 77 | || CVmObject::is_of_metaclass(meta)); |
| | 78 | } |
| | 79 | |
| | 80 | /* create dynamically using stack arguments */ |
| | 81 | static vm_obj_id_t create_from_stack(VMG_ const uchar **pc_ptr, |
| | 82 | uint argc); |
| | 83 | |
| | 84 | /* |
| | 85 | * call a static property - we don't have any of our own, so simply |
| | 86 | * "inherit" the base class handling |
| | 87 | */ |
| | 88 | static int call_stat_prop(VMG_ vm_val_t *result, |
| | 89 | const uchar **pc_ptr, uint *argc, |
| | 90 | vm_prop_id_t prop) |
| | 91 | { |
| | 92 | /* defer to our base class */ |
| | 93 | return CVmObject::call_stat_prop(vmg_ result, pc_ptr, argc, prop); |
| | 94 | } |
| | 95 | |
| | 96 | /* notify of deletion */ |
| | 97 | void notify_delete(VMG_ int in_root_set); |
| | 98 | |
| | 99 | /* set a property */ |
| | 100 | void set_prop(VMG_ class CVmUndo *undo, |
| | 101 | vm_obj_id_t self, vm_prop_id_t prop, const vm_val_t *val); |
| | 102 | |
| | 103 | /* get a property */ |
| | 104 | int get_prop(VMG_ vm_prop_id_t prop, vm_val_t *val, |
| | 105 | vm_obj_id_t self, vm_obj_id_t *source_obj, uint *argc); |
| | 106 | |
| | 107 | /* undo operations - we are immutable and hence keep no undo */ |
| | 108 | void notify_new_savept() { } |
| | 109 | void apply_undo(VMG_ struct CVmUndoRecord *) { } |
| | 110 | void mark_undo_ref(VMG_ struct CVmUndoRecord *) { } |
| | 111 | void remove_stale_undo_weak_ref(VMG_ struct CVmUndoRecord *) { } |
| | 112 | |
| | 113 | /* mark references */ |
| | 114 | void mark_refs(VMG_ uint); |
| | 115 | |
| | 116 | /* remove stale weak references - we have no weak references */ |
| | 117 | void remove_stale_weak_refs(VMG0_) { } |
| | 118 | |
| | 119 | /* load from an image file */ |
| | 120 | void load_from_image(VMG_ vm_obj_id_t, const char *ptr, size_t); |
| | 121 | |
| | 122 | /* perform post-load initialization */ |
| | 123 | void post_load_init(VMG_ vm_obj_id_t self); |
| | 124 | |
| | 125 | /* rebuild for image file */ |
| | 126 | virtual ulong rebuild_image(VMG_ char *buf, ulong buflen); |
| | 127 | |
| | 128 | /* convert to constant data */ |
| | 129 | virtual void convert_to_const_data(VMG_ class CVmConstMapper *mapper, |
| | 130 | vm_obj_id_t self); |
| | 131 | |
| | 132 | /* save to a file */ |
| | 133 | void save_to_file(VMG_ class CVmFile *fp); |
| | 134 | |
| | 135 | /* restore from a file */ |
| | 136 | void restore_from_file(VMG_ vm_obj_id_t self, |
| | 137 | class CVmFile *fp, class CVmObjFixup *fixup); |
| | 138 | |
| | 139 | /* get my compiled pattern */ |
| | 140 | re_compiled_pattern *get_pattern(VMG0_) { return get_ext()->pat; } |
| | 141 | |
| | 142 | /* am I a pattern object? */ |
| | 143 | static int is_pattern_obj(VMG_ vm_obj_id_t obj) |
| | 144 | { return vm_objp(vmg_ obj)->is_of_metaclass(metaclass_reg_); } |
| | 145 | |
| | 146 | protected: |
| | 147 | /* create with no extension */ |
| | 148 | CVmObjPattern() { ext_ = 0; } |
| | 149 | |
| | 150 | /* create with a given pattern object and source string value */ |
| | 151 | CVmObjPattern(VMG_ re_compiled_pattern *pat, const vm_val_t *src_str); |
| | 152 | |
| | 153 | /* set my compiled pattern data structure */ |
| | 154 | void set_pattern(re_compiled_pattern *pat) { get_ext()->pat = pat; } |
| | 155 | |
| | 156 | /* get/set my original source string value */ |
| | 157 | const vm_val_t *get_orig_str() const { return &get_ext()->str; } |
| | 158 | void set_orig_str(const vm_val_t *val) { get_ext()->str = *val; } |
| | 159 | |
| | 160 | /* get my extension data */ |
| | 161 | vmobj_pat_ext *get_ext() const { return (vmobj_pat_ext *)ext_; } |
| | 162 | |
| | 163 | /* property evaluator - undefined property */ |
| | 164 | int getp_undef(VMG_ vm_obj_id_t, vm_val_t *, uint *) { return FALSE; } |
| | 165 | |
| | 166 | /* property evaluator - get my original string */ |
| | 167 | int getp_get_str(VMG_ vm_obj_id_t, vm_val_t *val, uint *argc); |
| | 168 | |
| | 169 | /* property evaluation function table */ |
| | 170 | static int (CVmObjPattern::*func_table_[])(VMG_ vm_obj_id_t self, |
| | 171 | vm_val_t *retval, uint *argc); |
| | 172 | }; |
| | 173 | |
| | 174 | /* ------------------------------------------------------------------------ */ |
| | 175 | /* |
| | 176 | * Registration table object |
| | 177 | */ |
| | 178 | class CVmMetaclassPattern: public CVmMetaclass |
| | 179 | { |
| | 180 | public: |
| | 181 | /* get the global name */ |
| | 182 | const char *get_meta_name() const { return "regex-pattern/030000"; } |
| | 183 | |
| | 184 | /* create from image file */ |
| | 185 | void create_for_image_load(VMG_ vm_obj_id_t id) |
| | 186 | { |
| | 187 | new (vmg_ id) CVmObjPattern(); |
| | 188 | G_obj_table->set_obj_gc_characteristics(id, TRUE, FALSE); |
| | 189 | } |
| | 190 | |
| | 191 | /* create from restoring from saved state */ |
| | 192 | void create_for_restore(VMG_ vm_obj_id_t id) |
| | 193 | { |
| | 194 | new (vmg_ id) CVmObjPattern(); |
| | 195 | G_obj_table->set_obj_gc_characteristics(id, TRUE, FALSE); |
| | 196 | } |
| | 197 | |
| | 198 | /* create dynamically using stack arguments */ |
| | 199 | vm_obj_id_t create_from_stack(VMG_ const uchar **pc_ptr, uint argc) |
| | 200 | { return CVmObjPattern::create_from_stack(vmg_ pc_ptr, argc); } |
| | 201 | |
| | 202 | /* call a static property */ |
| | 203 | int call_stat_prop(VMG_ vm_val_t *result, |
| | 204 | const uchar **pc_ptr, uint *argc, |
| | 205 | vm_prop_id_t prop) |
| | 206 | { |
| | 207 | return CVmObjPattern::call_stat_prop(vmg_ result, pc_ptr, argc, prop); |
| | 208 | } |
| | 209 | }; |
| | 210 | |
| | 211 | #endif /* VMPAT_H */ |
| | 212 | |
| | 213 | /* |
| | 214 | * Register the class |
| | 215 | */ |
| | 216 | VM_REGISTER_METACLASS(CVmObjPattern) |
| | 217 | |