Annotation of parser3/src/types/pa_value.C, revision 1.9.2.3
1.1 paf 1: /** @file
2: Parser: Value class.
3:
1.9 paf 4: Copyright (c) 2001, 2003 ArtLebedev Group (http://www.artlebedev.com)
1.1 paf 5: Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)
1.2 paf 6: */
1.1 paf 7:
1.9.2.3 ! paf 8: static const char* IDENT_VALUE_C="$Date: 2003/01/27 15:07:48 $";
1.1 paf 9:
10: #include "pa_value.h"
11: #include "pa_vstateless_class.h"
1.4 paf 12: #include "pa_vmethod_frame.h"
1.9.2.3 ! paf 13:
! 14: // globals
! 15:
! 16: StringPtr value_name(new String(VALUE_NAME));
! 17:
! 18: // methods
1.9.2.2 paf 19:
20: VFilePtr Value::as_vfile(String::Untaint_lang /*lang*/=String::UL_UNSPECIFIED,
21: bool /*origins_mode*/=false) {
22: bark("(%s) does not have file value");
23: return VFilePtr(0); //never
24: }
1.1 paf 25:
26: /// call this before invoking to ensure proper actual numbered params count
27: void Method::check_actual_numbered_params(
1.8 paf 28: Value& self, const String& actual_name, Array *actual_numbered_params) const {
1.1 paf 29:
30: int actual_count=actual_numbered_params?actual_numbered_params->size():0;
31: if(actual_count<min_numbered_params_count) // not proper count? bark
32: throw Exception("parser.runtime",
33: &actual_name,
34: "native method of %s (%s) accepts minimum %d parameter(s) (%d present)",
1.8 paf 35: self.get_class()->name_cstr(),
36: self.type(),
1.1 paf 37: min_numbered_params_count,
38: actual_count);
39:
40: }
1.4 paf 41:
42: Junction::Junction(Pool& apool,
1.8 paf 43: Value& aself,
1.7 paf 44: const Method *amethod,
1.4 paf 45: VMethodFrame *amethod_frame,
46: Value *arcontext,
47: WContext *awcontext,
48: const Array *acode) : Pooled(apool),
49:
50: self(aself),
1.7 paf 51: method(amethod),
1.4 paf 52: method_frame(amethod_frame),
53: rcontext(arcontext),
54: wcontext(awcontext),
55: code(acode) {
1.5 paf 56: if(wcontext)
57: wcontext->attach_junction(*this);
1.4 paf 58: }
59:
1.5 paf 60: void Junction::reattach(WContext *new_wcontext) {
61: if(new_wcontext)
62: wcontext=new_wcontext;
63: else {
64: method_frame=0;
65: rcontext=0;
66: wcontext=0;
67: }
1.4 paf 68: }
69:
70: /*
71: void Junction::change_context(Junction *source) {
72: if(source) {
73: method_frame=source->method_frame;
74: rcontext=source->rcontext;
75: wcontext=source->wcontext;
76: } else {
77: method_frame=rcontext=0;
78: wcontext=0;
79: }
80: }
81: */
82:
1.9.2.1 paf 83: // attributed meaning
84:
85: static size_t date_attribute(const VDate& vdate, char *buf, size_t buf_size) {
86: const char month_names[12][4]={
87: "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
88: const char days[7][4]={
89: "Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
90:
91: time_t when=vdate.get_time();
92: struct tm *tms=gmtime(&when);
93: if(!tms)
94: throw Exception(0,
95: 0,
96: "bad time in attribute value (seconds from epoch=%ld)", when);
97: return snprintf(buf, MAX_STRING, "%s, %.2d-%s-%.4d %.2d:%.2d:%.2d GMT",
98: days[tms->tm_wday],
99: tms->tm_mday,month_names[tms->tm_mon],tms->tm_year+1900,
100: tms->tm_hour,tms->tm_min,tms->tm_sec);
101: }
102: static void append_attribute_meaning(String& result,
103: Value& value, String::Untaint_lang lang, bool forced) {
104: if(const String *string=value.get_string())
105: result.append(string->join_chains(result.pool(), 0), lang, forced);
106: else
107: if(Value *vdate=value.as(VDATE_TYPE, false)) {
108: char *buf=(char *)result.malloc(MAX_STRING);
109: size_t size=date_attribute(*static_cast<VDate *>(vdate),
110: buf, MAX_STRING);
111:
112: result.APPEND_CLEAN(buf, size, "converted from date", 0);
113: } else
114: throw Exception("parser.runtime",
115: &result,
116: "trying to append here neither string nor date (%s)",
117: value.type());
118: }
119: #ifndef DOXYGEN
120: struct Attributed_meaning_info {
121: String *header; // header line being constructed
122: String::Untaint_lang lang; // language in which to append to that line
123: bool forced; // do they force that lang?
124: };
125: #endif
126: static void append_attribute_subattribute(const Hash::Key& akey, Hash::Val *avalue,
127: void *info) {
128: if(akey==VALUE_NAME)
129: return;
130:
131: Attributed_meaning_info& ami=*static_cast<Attributed_meaning_info *>(info);
132:
133: // ...; charset=windows1251
134: *ami.header << "; ";
135: ami.header->append(akey, ami.lang, ami.forced);
136: *ami.header << "=";
137: append_attribute_meaning(*ami.header, *static_cast<Value *>(avalue), ami.lang, ami.forced);
138: }
139: const String& attributed_meaning_to_string(Value& meaning,
140: String::Untaint_lang lang, bool forced) {
141: String &result=*new(meaning.pool()) String(meaning.pool());
142: if(Hash *hash=meaning.get_hash(0)) {
143: // $value(value) $subattribute(subattribute value)
144: if(Value *value=static_cast<Value *>(hash->get(*value_name)))
145: append_attribute_meaning(result, *value, lang, forced);
146:
147: Attributed_meaning_info attributed_meaning_info={&result, lang};
148: hash->for_each(append_attribute_subattribute, &attributed_meaning_info);
149: } else // result value
150: append_attribute_meaning(result, meaning, lang, forced);
151:
152: return result;
153: }
E-mail: