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